[
  {
    "path": ".actrc",
    "content": ""
  },
  {
    "path": ".codespellrc",
    "content": "[codespell]\n# Ref: https://github.com/codespell-project/codespell#using-a-config-file\nskip = .git*,go.sum,package-lock.json,*.min.*,.codespellrc,testdata,./pkg/runner/hashfiles/index.js\ncheck-hidden = true\nignore-regex = .*Te\\{0\\}st.*\n# ignore-words-list =\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nindent_style = tab\nindent_size = 4\n\n[{*.md,*_test.go}]\nindent_style = unset\nindent_size = unset\n\n[**/Dockerfile]\nindent_style = space\nindent_size = 2\n\n[*.{yml,yaml,js,json,sh,nuspec}]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: cplee\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: Bug report\ndescription: Use this template for reporting bugs/issues.\nlabels:\n  - 'kind/bug'\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this bug report!\n  - type: textarea\n    id: act-debug\n    attributes:\n      label: Bug report info\n      render: plain text\n      description: |\n        Output of `act --bug-report`\n      placeholder: |\n        act --bug-report\n    validations:\n      required: true\n  - type: textarea\n    id: act-command\n    attributes:\n      label: Command used with act\n      description: |\n        Please paste your whole command\n      placeholder: |\n        act -P ubuntu-latest=node:12 -v -d ...\n      render: sh\n    validations:\n      required: true\n  - type: textarea\n    id: what-happened\n    attributes:\n      label: Describe issue\n      description: |\n        Also tell us what did you expect to happen?\n      placeholder: |\n        Describe issue\n    validations:\n      required: true\n  - type: input\n    id: repo\n    attributes:\n      label: Link to GitHub repository\n      description: |\n        Provide link to GitHub repository, you can skip it if the repository is private or you don't have it on GitHub, otherwise please provide it as it might help us troubleshoot problem\n      placeholder: |\n        https://github.com/nektos/act\n    validations:\n      required: false\n  - type: textarea\n    id: workflow\n    attributes:\n      label: Workflow content\n      description: |\n        Please paste your **whole** workflow here\n      placeholder: |\n        name: My workflow\n        on: ['push', 'schedule']\n        jobs:\n          test:\n            runs-on: ubuntu-latest\n          env:\n            KEY: VAL\n        [...]\n      render: yml\n    validations:\n      required: true\n  - type: textarea\n    id: logs\n    attributes:\n      label: Relevant log output\n      description: |\n        Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. Please verify that the log output doesn't contain any sensitive data.\n      render: sh\n      placeholder: |\n        Use `act -v` for verbose output\n    validations:\n      required: true\n  - type: textarea\n    id: additional-info\n    attributes:\n      label: Additional information\n      placeholder: |\n        Additional information that doesn't fit elsewhere\n    validations:\n      required: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: true\ncontact_links:\n  - name: Start a discussion\n    url: https://github.com/nektos/act/discussions/new\n    about: You can ask for help here!\n  - name: Want to contribute to act?\n    url: https://github.com/nektos/act/blob/master/CONTRIBUTING.md\n    about: Be sure to read contributing guidelines!\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_template.yml",
    "content": "name: Feature request\ndescription: Use this template for requesting a feature/enhancement.\nlabels:\n  - 'kind/feature-request'\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Please note that incompatibility with GitHub Actions should be opened as a bug report, not a new feature.\n  - type: input\n    id: act-version\n    attributes:\n      label: Act version\n      description: |\n        What version of `act` are you using? Version can be obtained via `act --version`\n        If you've built it from source, please provide commit hash\n      placeholder: |\n        act --version\n    validations:\n      required: true\n  - type: textarea\n    id: feature\n    attributes:\n      label: Feature description\n      description: Describe feature that you would like to see\n      placeholder: ...\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/wiki_issue.yml",
    "content": "name: Wiki issue\ndescription: Report issue/improvement ragarding documentation (wiki)\nlabels:\n  - 'kind/discussion'\n  - 'area/docs'\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to fill out this issue!\n  - type: textarea\n    id: details\n    attributes:\n      label: Details\n      description: |\n        Describe issue\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/actions/choco/Dockerfile",
    "content": "FROM alpine:3.21\n\nARG CHOCOVERSION=1.1.0\n\nRUN apk add --no-cache bash ca-certificates git \\\n  && apk --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community add mono mono-dev \\\n  && cert-sync /etc/ssl/certs/ca-certificates.crt \\\n  && wget \"https://github.com/chocolatey/choco/archive/${CHOCOVERSION}.tar.gz\" -O- | tar -xzf - \\\n  && cd choco-\"${CHOCOVERSION}\" \\\n  && chmod +x build.sh zip.sh \\\n  && ./build.sh -v \\\n  && mv ./code_drop/chocolatey/console /opt/chocolatey \\\n  && mkdir -p /opt/chocolatey/lib \\\n  && rm -rf /choco-\"${CHOCOVERSION}\" \\\n  && apk del mono-dev \\\n  && rm -rf /var/cache/apk/*\n\nENV ChocolateyInstall=/opt/chocolatey\nCOPY entrypoint.sh /entrypoint.sh\nENTRYPOINT [\"/entrypoint.sh\"]\n"
  },
  {
    "path": ".github/actions/choco/action.yml",
    "content": "name: 'Chocolatey Packager'\ndescription: 'Create the choco package and push it'\ninputs:\n  version:\n    description: 'Version of package'\n    required: false\n  apiKey:\n    description: 'API Key for chocolately'\n    required: false\n  push:\n    description: 'Option for if package is going to be pushed'\n    required: false\n    default: 'false'\nruns:\n  using: 'docker'\n  image: 'Dockerfile'\n"
  },
  {
    "path": ".github/actions/choco/entrypoint.sh",
    "content": "#!/bin/bash\n\nset -e\n\nfunction choco {\n  mono /opt/chocolatey/choco.exe \"$@\" --allow-unofficial --nocolor\n}\n\nfunction get_version {\n  local version=${INPUT_VERSION:-$(git describe --tags)}\n  version=(${version//[!0-9.-]/})\n  local version_parts=(${version//-/ })\n  version=${version_parts[0]}\n  if [ ${#version_parts[@]} -gt 1 ]; then\n    version=${version_parts}.${version_parts[1]}\n  fi\n  echo \"$version\"\n}\n\n## Determine the version to pack\nVERSION=$(get_version)\necho \"Packing version ${VERSION} of act\"\nrm -f act-cli.*.nupkg\nmkdir -p tools\ncp LICENSE tools/LICENSE.txt\ncp VERIFICATION tools/VERIFICATION.txt\ncp dist/act_windows_amd64_v1/act.exe tools/\nchoco pack act-cli.nuspec --version ${VERSION}\nif [[ \"$INPUT_PUSH\" == \"true\" ]]; then\n  choco push act-cli.${VERSION}.nupkg --api-key ${INPUT_APIKEY} -s https://push.chocolatey.org/ --timeout 180\nfi\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: 'github-actions'\n    directory: '/'\n    schedule:\n      interval: 'monthly'\n    groups:\n      dependencies:\n        patterns:\n        - '*'\n  - package-ecosystem: 'gomod'\n    directory: '/'\n    schedule:\n      interval: 'monthly'\n    groups:\n      dependencies:\n        patterns:\n        - '*'\n"
  },
  {
    "path": ".github/workflows/.gitignore",
    "content": "test-*.yml\n"
  },
  {
    "path": ".github/workflows/checks.yml",
    "content": "name: checks\non: [pull_request, workflow_dispatch]\n\nconcurrency:\n  cancel-in-progress: true\n  group: ${{ github.workflow }}-${{ github.ref }}\n\nenv:\n  ACT_OWNER: ${{ github.repository_owner }}\n  ACT_REPOSITORY: ${{ github.repository }}\n  CGO_ENABLED: 0\n\njobs:\n  lint:\n    name: lint\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n      - uses: golangci/golangci-lint-action@v6.5.0\n        with:\n          version: v1.64.8\n      - uses: megalinter/megalinter/flavors/go@v8.4.2\n        env:\n          DEFAULT_BRANCH: master\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          VALIDATE_ALL_CODEBASE: false\n          GITHUB_STATUS_REPORTER: ${{ !env.ACT }}\n          GITHUB_COMMENT_REPORTER: ${{ !env.ACT }}\n\n  test-linux:\n    name: test-linux\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 2\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v3\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n      - name: Run Tests\n        run: go run gotest.tools/gotestsum@latest --junitfile unit-tests.xml --format pkgname -- -v -cover -coverpkg=./... -coverprofile=coverage.txt -covermode=atomic -timeout 20m ./...\n      - name: Test Summary\n        uses: test-summary/action@v2\n        with:\n          paths: \"unit-tests.xml\"\n        if: always()\n      - name: Run act from cli\n        run: go run main.go -P ubuntu-latest=node:16-buster-slim -C ./pkg/runner/testdata/ -W ./basic/push.yml\n      - name: Run act from cli without docker support\n        run: go run -tags WITHOUT_DOCKER main.go -P ubuntu-latest=-self-hosted -C ./pkg/runner/testdata/ -W ./local-action-js/push.yml\n      - name: Upload Codecov report\n        uses: codecov/codecov-action@v5\n        with:\n          files: coverage.txt\n          fail_ci_if_error: true # optional (default = false)\n          token: ${{ secrets.CODECOV_TOKEN }}\n\n  test-host:\n    strategy:\n      matrix:\n        os:\n          - windows-latest\n          - macos-latest\n    name: test-host-${{matrix.os}}\n    runs-on: ${{matrix.os}}\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 2\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n      - name: Run Tests\n        run: go run gotest.tools/gotestsum@latest --junitfile unit-tests.xml --format pkgname -- -v -cover -coverpkg=./... -coverprofile=coverage.txt -covermode=atomic -timeout 20m -run ^TestRunEventHostEnvironment$ ./...\n        shell: bash\n      - name: Test Summary\n        uses: test-summary/action@v2\n        with:\n          paths: \"unit-tests.xml\"\n        if: always()\n\n\n  snapshot:\n    name: snapshot\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n      - name: GoReleaser\n        uses: goreleaser/goreleaser-action@v6\n        with:\n          version: latest\n          args: release --snapshot --clean\n      - name: Capture x86_64 (64-bit) Linux binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-linux-amd64\n          path: dist/act_linux_amd64_v1/act\n      - name: Capture i386 (32-bit) Linux binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-linux-i386\n          path: dist/act_linux_386/act\n      - name: Capture arm64 (64-bit) Linux binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-linux-arm64\n          path: dist/act_linux_arm64/act\n      - name: Capture armv6 (32-bit) Linux binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-linux-armv6\n          path: dist/act_linux_arm_6/act\n      - name: Capture armv7 (32-bit) Linux binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-linux-armv7\n          path: dist/act_linux_arm_7/act\n      - name: Capture riscv64 (64-bit) Linux binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-linux-riscv64\n          path: dist/act_linux_riscv64/act\n      - name: Capture x86_64 (64-bit) Windows binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-windows-amd64\n          path: dist/act_windows_amd64_v1/act.exe\n      - name: Capture i386 (32-bit) Windows binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-windows-i386\n          path: dist/act_windows_386/act.exe\n      - name: Capture arm64 (64-bit) Windows binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-windows-arm64\n          path: dist/act_windows_arm64/act.exe\n      - name: Capture armv7 (32-bit) Windows binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-windows-armv7\n          path: dist/act_windows_arm_7/act.exe\n      - name: Capture x86_64 (64-bit) MacOS binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-macos-amd64\n          path: dist/act_darwin_amd64_v1/act\n      - name: Capture arm64 (64-bit) MacOS binary\n        if: ${{ !env.ACT }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: act-macos-arm64\n          path: dist/act_darwin_arm64/act\n      - name: Chocolatey\n        uses: ./.github/actions/choco\n        with:\n          version: v0.0.0-pr\n"
  },
  {
    "path": ".github/workflows/codespell.yml",
    "content": "# Codespell configuration is within .codespellrc\n---\nname: Codespell\n\non:\n  push:\n    branches: [master]\n  pull_request:\n    branches: [master]\n\npermissions:\n  contents: read\n\njobs:\n  codespell:\n    name: Check for spelling errors\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Codespell\n        uses: codespell-project/actions-codespell@v2\n"
  },
  {
    "path": ".github/workflows/promote.yml",
    "content": "name: promote\non:\n  schedule:\n    - cron: '0 2 1 * *'\n  workflow_dispatch: {}\n\njobs:\n  release:\n    name: promote\n    runs-on: ubuntu-latest\n    environment: promote\n    steps:\n      - uses: actions/checkout@v4\n        id: checkout\n        env:\n          has_promote_token: ${{ secrets.PROMOTE_TOKEN && '1' || '' }}\n        if: env.has_promote_token\n        with:\n          fetch-depth: 0\n          ref: master\n          token: ${{ secrets.PROMOTE_TOKEN }}\n      - uses: fregante/setup-git-user@v2\n        if: steps.checkout.conclusion != 'skipped'\n      - uses: actions/setup-go@v5\n        if: steps.checkout.conclusion != 'skipped'\n        with:\n          go-version-file: go.mod\n      - run: make promote\n        if: steps.checkout.conclusion != 'skipped'\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: release\non:\n  push:\n    tags:\n      - v*\n\npermissions:\n  contents: write\n  actions: write\n\njobs:\n  release:\n    name: release\n    runs-on: ubuntu-latest\n    environment: release\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n      - name: GoReleaser\n        uses: goreleaser/goreleaser-action@v6\n        with:\n          version: latest\n          args: release --clean\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      - name: Winget\n        uses: vedantmgoyal2009/winget-releaser@v2\n        with:\n          identifier: nektos.act\n          installers-regex: '_Windows_\\w+\\.zip$'\n          token: ${{ secrets.WINGET_TOKEN }}\n      - name: Chocolatey\n        uses: ./.github/actions/choco\n        with:\n          version: ${{ github.ref }}\n          apiKey: ${{ secrets.CHOCO_APIKEY }}\n          push: true\n      - name: GitHub CLI extension\n        uses: actions/github-script@v7\n        with:\n          github-token: ${{ secrets.GH_ACT_TOKEN }}\n          script: |\n            const mainRef = (await github.rest.git.getRef({\n              owner: 'nektos',\n              repo: 'gh-act',\n              ref: 'heads/main',\n            })).data;\n            console.log(mainRef);\n            github.rest.git.createRef({\n              owner: 'nektos',\n              repo: 'gh-act',\n              ref: context.ref,\n              sha: mainRef.object.sha,\n            });\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: 'Close stale issues'\non:\n  workflow_dispatch:\n\njobs:\n  stale:\n    name: Stale\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/stale@v9\n        with:\n          repo-token: ${{ secrets.GITHUB_TOKEN }}\n          stale-issue-message: 'Issue is stale and will be closed in 14 days unless there is new activity'\n          stale-pr-message: 'PR is stale and will be closed in 14 days unless there is new activity'\n          stale-issue-label: 'stale'\n          exempt-issue-labels: 'stale-exempt,kind/feature-request'\n          stale-pr-label: 'stale'\n          exempt-pr-labels: 'stale-exempt'\n          remove-stale-when-updated: 'True'\n          operations-per-run: 500\n          days-before-stale: 180\n          days-before-close: 14\n"
  },
  {
    "path": ".gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, build with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n/dist/\n.todo\n\n*.nupkg\n.vscode/\n.idea/\n\n# Path for actions cache created when running tests\npkg/runner/act/\n\n# act binary\ndist/local/act\n\ncoverage.txt\nunit-tests.xml\n\n.env\n.secrets\n\n# megalinter\nreport/\n"
  },
  {
    "path": ".gitleaksignore",
    "content": "b910a42edfab7a02b08a52ecef203fd419725642:pkg/container/testdata/docker-pull-options/config.json:generic-api-key:4\n710a3ac94c3dc0eaf680d417c87f37f92b4887f4:pkg/container/docker_pull_test.go:generic-api-key:45\n"
  },
  {
    "path": ".golangci.yml",
    "content": "# Minimum golangci-lint version required: v1.46.0\nrun:\n  timeout: 3m\n\nissues:\n  exclude-dirs:\n    - report # megalinter results+fixes\n  max-issues-per-linter: 0\n  max-same-issues: 0\n\nlinters-settings:\n  gocyclo:\n    # minimal code complexity to report, 30 by default (but we recommend 10-20)\n    min-complexity: 20\n  gocritic:\n    disabled-checks:\n      - ifElseChain\n  importas:\n    alias:\n      - pkg: 'github.com/sirupsen/logrus'\n        alias: log\n      - pkg: 'github.com/stretchr/testify/assert'\n        alias: assert\n  depguard:\n    rules:\n      main:\n        deny:\n          - pkg: github.com/pkg/errors\n            desc: Please use \"errors\" package from standard library\n          - pkg: gotest.tools/v3\n            desc: Please keep tests unified using only github.com/stretchr/testify\n          - pkg: log\n            desc: Please keep logging unified using only github.com/sirupsen/logrus\nlinters:\n  enable:\n    - gosimple\n    - staticcheck\n    - unused\n    - govet\n    - revive\n    - gocyclo\n    - gosec\n    - unconvert\n    - dupl\n    - nakedret\n    - prealloc\n    - copyloopvar\n    - gocritic\n    - goimports\n    - whitespace\n    - misspell\n    - depguard\n    - importas\n    - contextcheck\n    - nolintlint\n    - revive\n"
  },
  {
    "path": ".goreleaser.yml",
    "content": "version: 2\nbefore:\n  hooks:\n    - go mod tidy\nbuilds:\n  - env:\n      - CGO_ENABLED=0\n    goos:\n      - darwin\n      - linux\n      - windows\n    goarch:\n      - amd64\n      - '386'\n      - arm64\n      - arm\n      - riscv64\n    goarm:\n      - '6'\n      - '7'\n    ignore:\n      - goos: windows\n        goarm: '6'\nchecksum:\n  name_template: 'checksums.txt'\narchives:\n  - name_template: >-\n      {{ .ProjectName }}_\n      {{- title .Os }}_\n      {{- if eq .Arch \"amd64\" }}x86_64\n      {{- else if eq .Arch \"386\" }}i386\n      {{- else }}{{ .Arch }}{{ end }}\n      {{- if .Arm }}v{{ .Arm }}{{ end }}\n    format_overrides:\n      - goos: windows\n        formats: [zip]\nchangelog:\n  groups:\n    - title: 'New Features'\n      regexp: \"^.*feat[(\\\\w)]*:+.*$\"\n      order: 0\n    - title: 'Bug fixes'\n      regexp: \"^.*fix[(\\\\w)]*:+.*$\"\n      order: 1\n    - title: 'Documentation updates'\n      regexp: \"^.*docs[(\\\\w)]*:+.*$\"\n      order: 2\n    - title: 'Other'\n      order: 999\nrelease:\n  prerelease: auto\n  mode: append\n"
  },
  {
    "path": ".markdownlint.yml",
    "content": "# Default state for all rules\ndefault: true\n\n# MD013/line-length - Line length\nMD013:\n  line_length: 1024\n\n# MD033/no-inline-html - Inline HTML\nMD033: false\n\n# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading\nMD041: false\n"
  },
  {
    "path": ".mega-linter.yml",
    "content": "---\nAPPLY_FIXES: none\nDISABLE:\n  - ACTION\n  - BASH\n  - COPYPASTE\n  - DOCKERFILE\n  - GO\n  - JAVASCRIPT\n  - SPELL\nDISABLE_LINTERS:\n  - YAML_YAMLLINT\n  - MARKDOWN_MARKDOWN_TABLE_FORMATTER\n  - MARKDOWN_MARKDOWN_LINK_CHECK\n  - REPOSITORY_CHECKOV\n  - REPOSITORY_TRIVY\nFILTER_REGEX_EXCLUDE: (.*testdata/*|install.sh|pkg/container/docker_cli.go|pkg/container/DOCKER_LICENSE|VERSION)\nMARKDOWN_MARKDOWNLINT_CONFIG_FILE: .markdownlint.yml\nPARALLEL: false\nPRINT_ALPACA: false\n"
  },
  {
    "path": ".mergify.yml",
    "content": "merge_queue:\n  max_parallel_checks: 1\n\npull_request_rules:\n  - name: warn on conflicts\n    conditions:\n      - -draft\n      - -closed\n      - -merged\n      - conflict\n    actions:\n      label:\n        add:\n          - conflict\n  - name: remove conflict label if not needed\n    conditions:\n      - -conflict\n    actions:\n      label:\n        remove:\n          - conflict\n  - name: warn on needs-work\n    conditions:\n      - -draft\n      - -closed\n      - -merged\n      - or:\n          - check-failure=lint\n          - check-failure=test-linux\n          - check-failure=codecov/patch\n          - check-failure=codecov/project\n          - check-failure=snapshot\n    actions:\n      label:\n        add:\n          - needs-work\n  - name: remove needs-work label if not needed\n    conditions:\n      - check-success=lint\n      - check-success=test-linux\n      - check-success=codecov/patch\n      - check-success=codecov/project\n      - check-success=snapshot\n    actions:\n      label:\n        remove:\n          - needs-work\n  - name: Automatic merge on approval\n    conditions: []\n    actions:\n      queue:\nqueue_rules:\n  - name: default\n    batch_size: 1\n    queue_conditions: &queue_conditions\n      - '#changes-requested-reviews-by=0'\n      - or:\n          - 'approved-reviews-by=@nektos/act-committers'\n          - 'author~=^dependabot(|-preview)\\[bot\\]$'\n          - and:\n              - 'approved-reviews-by=@nektos/act-maintainers'\n              - '#approved-reviews-by>=2'\n          - and:\n              - 'author=@nektos/act-maintainers'\n              - 'approved-reviews-by=@nektos/act-maintainers'\n              - '#approved-reviews-by>=1'\n      - -draft\n      - -merged\n      - -closed\n      - check-success=lint\n      - check-success=test-linux\n      - check-success=codecov/patch\n      - check-success=codecov/project\n      - check-success=snapshot\n    merge_conditions: *queue_conditions\n    merge_method: squash\n"
  },
  {
    "path": ".prettierignore",
    "content": "**/testdata\npkg/runner/res\n"
  },
  {
    "path": ".prettierrc.yml",
    "content": "overrides:\n  - files: '*.yml'\n    options:\n      singleQuote: true\n  - files: '*.json'\n    options:\n      singleQuote: false\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Act\n\nHelp wanted! We'd love your contributions to Act. Please review the following guidelines before contributing. Also, feel free to propose changes to these guidelines by updating this file and submitting a pull request.\n\n- [I have a question...](#questions)\n- [I found a bug...](#bugs)\n- [I have a feature request...](#features)\n- [I have a contribution to share...](#process)\n\n## <a id=\"questions\"></a> Have a Question?\n\nPlease don't open a GitHub issue for questions about how to use `act`, as the goal is to use issues for managing bugs and feature requests. Issues that are related to general support will be closed and redirected to [discussions](https://github.com/nektos/act/discussions).\n\nFor all support related questions, please [open a discussion post](https://github.com/nektos/act/discussions/new/choose).\n\n## <a id=\"bugs\"></a> Found a Bug?\n\nIf you've identified a bug in `act`, please [submit an issue](#issue) to our GitHub repo: [nektos/act](https://github.com/nektos/act/issues/new). Please also feel free to submit a [Pull Request](#pr) with a fix for the bug!\n\n## <a id=\"features\"></a> Have a Feature Request?\n\nAll feature requests should start with [submitting an issue](#issue) documenting the user story and acceptance criteria. Again, feel free to submit a [Pull Request](#pr) with a proposed implementation of the feature.\n\n## <a id=\"process\"></a> Ready to Contribute\n\n### <a id=\"issue\"></a> Create an issue\n\nBefore submitting a new issue, please search the issues to make sure there isn't a similar issue doesn't already exist.\n\nAssuming no existing issues exist, please ensure you include required information when submitting the issue to ensure we can quickly reproduce your issue.\n\nWe may have additional questions and will communicate through the GitHub issue, so please respond back to our questions to help reproduce and resolve the issue as quickly as possible.\n\nNew issues can be created with in our [GitHub repo](https://github.com/nektos/act/issues/new).\n\n### <a id=\"pr\"></a>Pull Requests\n\nPull requests should target the `master` branch. Please also reference the issue from the description of the pull request using [special keyword syntax](https://help.github.com/articles/closing-issues-via-commit-messages/) to auto close the issue when the PR is merged. For example, include the phrase `fixes #14` in the PR description to have issue #14 auto close. Please send documentation updates for the [act user guide](https://nektosact.com) to [nektos/act-docs](https://github.com/nektos/act-docs).\n\n### <a id=\"style\"></a> Styleguide\n\nWhen submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible. Here are a few points to keep in mind:\n\n- Please run `go fmt ./...` before committing to ensure code aligns with go standards.\n- We use [`golangci-lint`](https://golangci-lint.run/) for linting Go code, run `golangci-lint run --fix` before submitting PR. Editors such as Visual Studio Code or JetBrains IntelliJ; with Go support plugin will offer `golangci-lint` automatically.\n- There are additional linters and formatters for files such as Markdown documents or YAML/JSON:\n  - Please refer to the [Makefile](Makefile) or [`lint` job in our workflow](.github/workflows/checks.yml) to see how to those linters/formatters work.\n  - You can lint codebase by running `go run main.go -j lint --env RUN_LOCAL=true` or `act -j lint --env RUN_LOCAL=true`\n  - In `Makefile`, there are tools that require `npx` which is shipped with `nodejs`.\n  - Our `Makefile` exports `GITHUB_TOKEN` from `~/.config/github/token`, you have been warned.\n  - You can run `make pr` to cleanup dependencies, format/lint code and run tests.\n- All dependencies must be defined in the `go.mod` file.\n  - Advanced IDEs and code editors (like VSCode) will take care of that, but to be sure, run `go mod tidy` to validate dependencies.\n- For details on the approved style, check out [Effective Go](https://golang.org/doc/effective_go.html).\n- Before running tests, please be aware that they are multi-architecture so for them to not fail, you need to run `docker run --privileged --rm tonistiigi/binfmt --install amd64,arm64` before ([more info available in #765](https://github.com/nektos/act/issues/765)).\n\nAlso, consider the original design principles:\n\n- **Polyglot** - There will be no prescribed language or framework for developing the microservices. The only requirement will be that the service will be run inside a container and exposed via an HTTP endpoint.\n- **Cloud Provider** - At this point, the tool will assume AWS for the cloud provider and will not be written in a cloud agnostic manner. However, this does not preclude refactoring to add support for other providers at a later time.\n- **Declarative** - All resource administration will be handled in a declarative vs. imperative manner. A file will be used to declared the desired state of the resources and the tool will simply assert the actual state matches the desired state. The tool will accomplish this by generating CloudFormation templates.\n- **Stateless** - The tool will not maintain its own state. Rather, it will rely on the CloudFormation stacks to determine the state of the platform.\n- **Secure** - All security will be managed by AWS IAM credentials. No additional authentication or authorization mechanisms will be introduced.\n\n### License\n\nBy contributing your code, you agree to license your contribution under the terms of the [MIT License](LICENSE).\n\nAll files are released with the MIT license.\n"
  },
  {
    "path": "IMAGES.md",
    "content": "# List of Docker images for `act`\n\n**Warning:** Below badges with size for each image are displaying size of **compressed image size in registry. After pulling the image, size can be drastically different due to Docker uncompressing the image layers.**\n\n## Images based on [`buildpack-deps`][hub/_/buildpack-deps]\n\n**Note 1: `node` images are based on Debian root filesystem, while it is extremely similar to Ubuntu, there might be some differences**\n\n**Note 2: `node` `-slim` images don't have `python` installed, if you want to use actions or software that is depending on `python`, you need to specify image manually**\n\n| Image                                 | Size                                                       |\n| ------------------------------------- | ---------------------------------------------------------- |\n| [`node:16-bullseye`][hub/_/node]      | ![`bullseye-size`][hub/_/node/16-bullseye/size]            |\n| [`node:16-bullseye-slim`][hub/_/node] | ![`micro-bullseye-size`][hub/_/node/16-bullseye-slim/size] |\n| [`node:16-buster`][hub/_/node]        | ![`buster-size`][hub/_/node/16-buster/size]                |\n| [`node:16-buster-slim`][hub/_/node]   | ![`micro-buster-size`][hub/_/node/16-buster-slim/size]     |\n\n**Note: `catthehacker/ubuntu` images are based on Ubuntu root filesystem**\n\n| Image                                                        | GitHub Repository                                             |\n| ------------------------------------------------------------ | ------------------------------------------------------------- |\n| [`catthehacker/ubuntu:act-latest`][ghcr/catthehacker/ubuntu] | [`catthehacker/docker-images`][gh/catthehacker/docker_images] |\n| [`catthehacker/ubuntu:act-22.04`][ghcr/catthehacker/ubuntu]  | [`catthehacker/docker-images`][gh/catthehacker/docker_images] |\n| [`catthehacker/ubuntu:act-20.04`][ghcr/catthehacker/ubuntu]  | [`catthehacker/docker-images`][gh/catthehacker/docker_images] |\n| [`catthehacker/ubuntu:act-18.04`][ghcr/catthehacker/ubuntu]  | [`catthehacker/docker-images`][gh/catthehacker/docker_images] |\n\n## Images based on [`actions/virtual-environments`][gh/actions/virtual-environments]\n\n**Note: `nektos/act-environments-ubuntu` have been last updated in February, 2020. It's recommended to update the image manually after `docker pull` if you decide to use it.**\n\n| Image                                                                             | Size                                                                       | GitHub Repository                                       |\n| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------- |\n| [`nektos/act-environments-ubuntu:18.04`][hub/nektos/act-environments-ubuntu]      | ![`nektos:18.04`][hub/nektos/act-environments-ubuntu/18.04/size]           | [`nektos/act-environments`][gh/nektos/act-environments] |\n| [`nektos/act-environments-ubuntu:18.04-lite`][hub/nektos/act-environments-ubuntu] | ![`nektos:18.04-lite`][hub/nektos/act-environments-ubuntu/18.04-lite/size] | [`nektos/act-environments`][gh/nektos/act-environments] |\n| [`nektos/act-environments-ubuntu:18.04-full`][hub/nektos/act-environments-ubuntu] | ![`nektos:18.04-full`][hub/nektos/act-environments-ubuntu/18.04-full/size] | [`nektos/act-environments`][gh/nektos/act-environments] |\n\n| Image                                                         | GitHub Repository                                                                     |\n| ------------------------------------------------------------- | ------------------------------------------------------------------------------------- |\n| [`catthehacker/ubuntu:full-latest`][ghcr/catthehacker/ubuntu] | [`catthehacker/virtual-environments-fork`][gh/catthehacker/virtual-environments-fork] |\n| [`catthehacker/ubuntu:full-20.04`][ghcr/catthehacker/ubuntu]  | [`catthehacker/virtual-environments-fork`][gh/catthehacker/virtual-environments-fork] |\n| [`catthehacker/ubuntu:full-18.04`][ghcr/catthehacker/ubuntu]  | [`catthehacker/virtual-environments-fork`][gh/catthehacker/virtual-environments-fork] |\n\nFeel free to make a pull request with your image added here\n\n[hub/_/buildpack-deps]: https://hub.docker.com/_/buildpack-deps\n[hub/_/node]: https://hub.docker.com/r/_/node\n[hub/_/node/16-bullseye/size]: https://img.shields.io/docker/image-size/_/node/16-bullseye\n[hub/_/node/16-bullseye-slim/size]: https://img.shields.io/docker/image-size/_/node/16-bullseye-slim\n[hub/_/node/16-buster/size]: https://img.shields.io/docker/image-size/_/node/16-buster\n[hub/_/node/16-buster-slim/size]: https://img.shields.io/docker/image-size/_/node/16-buster-slim\n[ghcr/catthehacker/ubuntu]: https://github.com/catthehacker/docker_images/pkgs/container/ubuntu\n[hub/nektos/act-environments-ubuntu]: https://hub.docker.com/r/nektos/act-environments-ubuntu\n[hub/nektos/act-environments-ubuntu/18.04/size]: https://img.shields.io/docker/image-size/nektos/act-environments-ubuntu/18.04\n[hub/nektos/act-environments-ubuntu/18.04-lite/size]: https://img.shields.io/docker/image-size/nektos/act-environments-ubuntu/18.04-lite\n[hub/nektos/act-environments-ubuntu/18.04-full/size]: https://img.shields.io/docker/image-size/nektos/act-environments-ubuntu/18.04-full\n\n<!--\n[hub/<username>/<image>]: https://hub.docker.com/r/[username]/[image]\n[hub/<username>/<image>/<tag>/size]: https://img.shields.io/docker/image-size/[username]/[image]/[tag]\n-->\n\n<!-- GitHub repository links -->\n\n[gh/nektos/act-environments]: https://github.com/nektos/act-environments\n[gh/actions/virtual-environments]: https://github.com/actions/virtual-environments\n[gh/catthehacker/docker_images]: https://github.com/catthehacker/docker_images\n[gh/catthehacker/virtual-environments-fork]: https://github.com/catthehacker/virtual-environments-fork\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "PREFIX ?= /usr/local\nVERSION ?= $(shell git describe --tags --dirty --always | sed -e 's/^v//')\nIS_SNAPSHOT = $(if $(findstring -, $(VERSION)),true,false)\nMAJOR_VERSION = $(word 1, $(subst ., ,$(VERSION)))\nMINOR_VERSION = $(word 2, $(subst ., ,$(VERSION)))\nPATCH_VERSION = $(word 3, $(subst ., ,$(word 1,$(subst -, , $(VERSION)))))\nNEW_VERSION ?= $(MAJOR_VERSION).$(MINOR_VERSION).$(shell echo $$(( $(PATCH_VERSION) + 1)) )\nGOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1\n\nfix = false\nifeq (true,$(fix))\n\tFIX = --fix\nendif\n\nACT ?= go run main.go\n\nHAS_TOKEN = $(if $(test -e ~/.config/github/token),true,false)\nifeq (true,$(HAS_TOKEN))\n\texport GITHUB_TOKEN := $(shell cat ~/.config/github/token)\nendif\n\n.PHONY: pr\npr: tidy format-all lint test\n\n.PHONY: build\nbuild:\n\tgo build -ldflags \"-X main.version=$(VERSION)\" -o dist/local/act main.go\n\n.PHONY: format\nformat:\n\tgo fmt ./...\n\n.PHONY: format-all\nformat-all:\n\tgo fmt ./...\n\tnpx prettier --write .\n\n.PHONY: test\ntest:\n\tgo test ./...\n\t$(ACT)\n\n.PHONY: lint-go\nlint-go:\n\tgolangci-lint run $(FIX)\n\n.PHONY: lint-js\nlint-js:\n\tnpx standard $(FIX)\n\n.PHONY: lint-md\nlint-md:\n\tnpx markdownlint . $(FIX)\n\n.PHONY: lint-rest\nlint-rest:\n\tdocker run --rm -it \\\n\t\t-v $(PWD):/tmp/lint \\\n\t\t-e GITHUB_STATUS_REPORTER=false \\\n\t\t-e GITHUB_COMMENT_REPORTER=false \\\n\t\tmegalinter/megalinter-go:v5\n\n.PHONY: lint\nlint: lint-go lint-rest\n\n.PHONY: lint-fix\nlint-fix: lint-md lint-go\n\n.PHONY: fix\nfix:\n\tmake lint-fix fix=true\n\n.PHONY: tidy\ntidy:\n\tgo mod tidy\n\n.PHONY: install\ninstall: build\n\t@cp dist/local/act $(PREFIX)/bin/act\n\t@chmod 755 $(PREFIX)/bin/act\n\t@act --version\n\n.PHONY: installer\ninstaller:\n\t@GO111MODULE=off go get github.com/goreleaser/godownloader\n\tgodownloader -r nektos/act -o install.sh\n\n.PHONY: promote\npromote:\n\t@git fetch --tags\n\t@echo \"VERSION:$(VERSION) IS_SNAPSHOT:$(IS_SNAPSHOT) NEW_VERSION:$(NEW_VERSION)\"\nifeq (false,$(IS_SNAPSHOT))\n\t@echo \"Unable to promote a non-snapshot\"\n\t@exit 1\nendif\nifneq ($(shell git status -s),)\n\t@echo \"Unable to promote a dirty workspace\"\n\t@exit 1\nendif\n\techo -n $(NEW_VERSION) > VERSION\n\tgit add VERSION\n\tgit commit -m \"chore: bump VERSION to $(NEW_VERSION)\"\n\tgit tag -a -m \"releasing v$(NEW_VERSION)\" v$(NEW_VERSION)\n\tgit push origin master\n\tgit push origin v$(NEW_VERSION)\n\n.PHONY: snapshot\nsnapshot:\n\tgoreleaser build \\\n\t\t--clean \\\n\t\t--single-target \\\n\t\t--snapshot\n\n.PHONY: clean all\n\n.PHONY: upgrade\nupgrade:\n\tgo get -u\n\tgo mod tidy\n\n# \"$(shell go env GOROOT)/bin/go\" allows us to use an outdated global go tool and use the build toolchain defined by the project\n# go build auto upgrades to the same toolchain version as defined in the go.mod file\n.PHONY: deps-tools\ndeps-tools: ## install tool dependencies\n\t\"$(shell go env GOROOT)/bin/go\" install $(GOVULNCHECK_PACKAGE)\n\n.PHONY: security-check\nsecurity-check: deps-tools\n\tGOEXPERIMENT= \"$(shell go env GOROOT)/bin/go\" run $(GOVULNCHECK_PACKAGE) -show color ./...\n"
  },
  {
    "path": "README.md",
    "content": "![act-logo](https://raw.githubusercontent.com/wiki/nektos/act/img/logo-150.png)\n\n# Overview [![push](https://github.com/nektos/act/workflows/push/badge.svg?branch=master&event=push)](https://github.com/nektos/act/actions) [![Go Report Card](https://goreportcard.com/badge/github.com/nektos/act)](https://goreportcard.com/report/github.com/nektos/act) [![awesome-runners](https://img.shields.io/badge/listed%20on-awesome--runners-blue.svg)](https://github.com/jonico/awesome-runners)\n\n> \"Think globally, `act` locally\"\n\nRun your [GitHub Actions](https://developer.github.com/actions/) locally! Why would you want to do this? Two reasons:\n\n- **Fast Feedback** - Rather than having to commit/push every time you want to test out the changes you are making to your `.github/workflows/` files (or for any changes to embedded GitHub actions), you can use `act` to run the actions locally. The [environment variables](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) and [filesystem](https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners#filesystems-on-github-hosted-runners) are all configured to match what GitHub provides.\n- **Local Task Runner** - I love [make](<https://en.wikipedia.org/wiki/Make_(software)>). However, I also hate repeating myself. With `act`, you can use the GitHub Actions defined in your `.github/workflows/` to replace your `Makefile`!\n\n> [!TIP]\n> **Now Manage and Run Act Directly From VS Code!**<br/>\n> Check out the [GitHub Local Actions](https://sanjulaganepola.github.io/github-local-actions-docs/) Visual Studio Code extension which allows you to leverage the power of `act` to run and test workflows locally without leaving your editor.\n\n# How Does It Work?\n\nWhen you run `act` it reads in your GitHub Actions from `.github/workflows/` and determines the set of actions that need to be run. It uses the Docker API to either pull or build the necessary images, as defined in your workflow files and finally determines the execution path based on the dependencies that were defined. Once it has the execution path, it then uses the Docker API to run containers for each action based on the images prepared earlier. The [environment variables](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) and [filesystem](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#file-systems) are all configured to match what GitHub provides.\n\nLet's see it in action with a [sample repo](https://github.com/cplee/github-actions-demo)!\n\n![Demo](https://raw.githubusercontent.com/wiki/nektos/act/quickstart/act-quickstart-2.gif)\n\n# Act User Guide\n\nPlease look at the [act user guide](https://nektosact.com) for more documentation.\n\n# Support\n\nNeed help? Ask in [discussions](https://github.com/nektos/act/discussions)!\n\n# Contributing\n\nWant to contribute to act? Awesome! Check out the [contributing guidelines](CONTRIBUTING.md) to get involved.\n\n## Manually building from source\n\n- Install Go tools 1.20+ - (<https://golang.org/doc/install>)\n- Clone this repo `git clone git@github.com:nektos/act.git`\n- Run unit tests with `make test`\n- Build and install: `make install`\n"
  },
  {
    "path": "VERIFICATION",
    "content": "VERIFICATION\nVerification is intended to assist the Chocolatey moderators and community\nin verifying that this package's contents are trustworthy.\n\nChecksums: https://github.com/nektos/act/releases, in the checksums.txt file\n"
  },
  {
    "path": "VERSION",
    "content": "0.2.84"
  },
  {
    "path": "act-cli.nuspec",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Do not remove this test for UTF-8: if “Ω” doesn’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one. -->\n<package xmlns=\"http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd\">\n  <metadata>\n    <id>act-cli</id>\n    <version>0.0.0</version>\n    <packageSourceUrl>https://github.com/nektos/act</packageSourceUrl>\n    <owners>nektos</owners>\n    <title>act (GitHub Actions CLI)</title>\n    <authors>nektos</authors>\n    <projectUrl>https://github.com/nektos/act</projectUrl>\n    <iconUrl>https://raw.githubusercontent.com/wiki/nektos/act/img/logo-150.png</iconUrl>\n    <copyright>Nektos</copyright>\n    <licenseUrl>https://raw.githubusercontent.com/nektos/act/master/LICENSE</licenseUrl>\n    <requireLicenseAcceptance>true</requireLicenseAcceptance>\n    <projectSourceUrl>https://github.com/nektos/act</projectSourceUrl>\n    <docsUrl>https://raw.githubusercontent.com/nektos/act/master/README.md</docsUrl>\n    <bugTrackerUrl>https://github.com/nektos/act/issues</bugTrackerUrl>\n    <tags>act github-actions actions golang ci devops</tags>\n    <summary>Run your GitHub Actions locally 🚀</summary>\n    <description>Run your GitHub Actions locally 🚀</description>\n  </metadata>\n  <files>\n    <file src=\"tools/**\" target=\"tools\" />\n  </files>\n</package>\n"
  },
  {
    "path": "cmd/dir.go",
    "content": "package cmd\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar (\n\tUserHomeDir  string\n\tCacheHomeDir string\n)\n\nfunc init() {\n\thome, err := os.UserHomeDir()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tUserHomeDir = home\n\n\tif v := os.Getenv(\"XDG_CACHE_HOME\"); v != \"\" {\n\t\tCacheHomeDir = v\n\t} else {\n\t\tCacheHomeDir = filepath.Join(UserHomeDir, \".cache\")\n\t}\n}\n"
  },
  {
    "path": "cmd/execute_test.go",
    "content": "package cmd\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n)\n\n// Helper function to test main with different os.Args\nfunc testMain(args []string) (exitCode int) {\n\t// Save original os.Args and defer restoring it\n\torigArgs := os.Args\n\tdefer func() { os.Args = origArgs }()\n\n\t// Save original os.Exit and defer restoring it\n\tdefer func() { exitFunc = os.Exit }()\n\n\t// Mock os.Exit\n\tfakeExit := func(code int) {\n\t\texitCode = code\n\t}\n\texitFunc = fakeExit\n\n\t// Mock os.Args\n\tos.Args = args\n\n\t// Run the main function\n\tExecute(context.Background(), \"\")\n\n\treturn exitCode\n}\n\nfunc TestMainHelp(t *testing.T) {\n\texitCode := testMain([]string{\"cmd\", \"--help\"})\n\tif exitCode != 0 {\n\t\tt.Errorf(\"Expected exit code 0, got %d\", exitCode)\n\t}\n}\n\nfunc TestMainNoArgsError(t *testing.T) {\n\texitCode := testMain([]string{\"cmd\"})\n\tif exitCode != 1 {\n\t\tt.Errorf(\"Expected exit code 1, got %d\", exitCode)\n\t}\n}\n"
  },
  {
    "path": "cmd/graph.go",
    "content": "package cmd\n\nimport (\n\t\"os\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nfunc drawGraph(plan *model.Plan) error {\n\tdrawings := make([]*common.Drawing, 0)\n\n\tjobPen := common.NewPen(common.StyleSingleLine, 96)\n\tarrowPen := common.NewPen(common.StyleNoLine, 97)\n\tfor i, stage := range plan.Stages {\n\t\tif i > 0 {\n\t\t\tdrawings = append(drawings, arrowPen.DrawArrow())\n\t\t}\n\n\t\tids := make([]string, 0)\n\t\tfor _, r := range stage.Runs {\n\t\t\tids = append(ids, r.String())\n\t\t}\n\t\tdrawings = append(drawings, jobPen.DrawBoxes(ids...))\n\t}\n\n\tmaxWidth := 0\n\tfor _, d := range drawings {\n\t\tif d.GetWidth() > maxWidth {\n\t\t\tmaxWidth = d.GetWidth()\n\t\t}\n\t}\n\n\tfor _, d := range drawings {\n\t\td.Draw(os.Stdout, maxWidth)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/input.go",
    "content": "package cmd\n\nimport (\n\t\"path/filepath\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// Input contains the input for the root command\ntype Input struct {\n\tactor                              string\n\tworkdir                            string\n\tworkflowsPath                      string\n\tautodetectEvent                    bool\n\teventPath                          string\n\treuseContainers                    bool\n\tbindWorkdir                        bool\n\tsecrets                            []string\n\tvars                               []string\n\tenvs                               []string\n\tinputs                             []string\n\tplatforms                          []string\n\tdryrun                             bool\n\tforcePull                          bool\n\tforceRebuild                       bool\n\tnoOutput                           bool\n\tenvfile                            string\n\tinputfile                          string\n\tsecretfile                         string\n\tvarfile                            string\n\tinsecureSecrets                    bool\n\tdefaultBranch                      string\n\tprivileged                         bool\n\tusernsMode                         string\n\tcontainerArchitecture              string\n\tcontainerDaemonSocket              string\n\tcontainerOptions                   string\n\tnoWorkflowRecurse                  bool\n\tuseGitIgnore                       bool\n\tgithubInstance                     string\n\tcontainerCapAdd                    []string\n\tcontainerCapDrop                   []string\n\tautoRemove                         bool\n\tartifactServerPath                 string\n\tartifactServerAddr                 string\n\tartifactServerPort                 string\n\tnoCacheServer                      bool\n\tcacheServerPath                    string\n\tcacheServerExternalURL             string\n\tcacheServerAddr                    string\n\tcacheServerPort                    uint16\n\tjsonLogger                         bool\n\tnoSkipCheckout                     bool\n\tremoteName                         string\n\treplaceGheActionWithGithubCom      []string\n\treplaceGheActionTokenWithGithubCom string\n\tmatrix                             []string\n\tactionCachePath                    string\n\tactionOfflineMode                  bool\n\tlogPrefixJobID                     bool\n\tnetworkName                        string\n\tuseNewActionCache                  bool\n\tlocalRepository                    []string\n\tlistOptions                        bool\n\tvalidate                           bool\n\tstrict                             bool\n\tconcurrentJobs                     int\n}\n\nfunc (i *Input) resolve(path string) string {\n\tbasedir, err := filepath.Abs(i.workdir)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tif path == \"\" {\n\t\treturn path\n\t}\n\tif !filepath.IsAbs(path) {\n\t\tpath = filepath.Join(basedir, path)\n\t}\n\treturn path\n}\n\n// Envfile returns path to .env\nfunc (i *Input) Envfile() string {\n\treturn i.resolve(i.envfile)\n}\n\n// Secretfile returns path to secrets\nfunc (i *Input) Secretfile() string {\n\treturn i.resolve(i.secretfile)\n}\n\nfunc (i *Input) Varfile() string {\n\treturn i.resolve(i.varfile)\n}\n\n// Workdir returns path to workdir\nfunc (i *Input) Workdir() string {\n\treturn i.resolve(\".\")\n}\n\n// WorkflowsPath returns path to workflow file(s)\nfunc (i *Input) WorkflowsPath() string {\n\treturn i.resolve(i.workflowsPath)\n}\n\n// EventPath returns the path to events file\nfunc (i *Input) EventPath() string {\n\treturn i.resolve(i.eventPath)\n}\n\n// Inputfile returns the path to the input file\nfunc (i *Input) Inputfile() string {\n\treturn i.resolve(i.inputfile)\n}\n"
  },
  {
    "path": "cmd/list.go",
    "content": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nfunc printList(plan *model.Plan) error {\n\ttype lineInfoDef struct {\n\t\tjobID   string\n\t\tjobName string\n\t\tstage   string\n\t\twfName  string\n\t\twfFile  string\n\t\tevents  string\n\t}\n\tlineInfos := []lineInfoDef{}\n\n\theader := lineInfoDef{\n\t\tjobID:   \"Job ID\",\n\t\tjobName: \"Job name\",\n\t\tstage:   \"Stage\",\n\t\twfName:  \"Workflow name\",\n\t\twfFile:  \"Workflow file\",\n\t\tevents:  \"Events\",\n\t}\n\n\tjobs := map[string]bool{}\n\tduplicateJobIDs := false\n\n\tjobIDMaxWidth := len(header.jobID)\n\tjobNameMaxWidth := len(header.jobName)\n\tstageMaxWidth := len(header.stage)\n\twfNameMaxWidth := len(header.wfName)\n\twfFileMaxWidth := len(header.wfFile)\n\teventsMaxWidth := len(header.events)\n\n\tfor i, stage := range plan.Stages {\n\t\tfor _, r := range stage.Runs {\n\t\t\tjobID := r.JobID\n\t\t\tline := lineInfoDef{\n\t\t\t\tjobID:   jobID,\n\t\t\t\tjobName: r.String(),\n\t\t\t\tstage:   strconv.Itoa(i),\n\t\t\t\twfName:  r.Workflow.Name,\n\t\t\t\twfFile:  r.Workflow.File,\n\t\t\t\tevents:  strings.Join(r.Workflow.On(), `,`),\n\t\t\t}\n\t\t\tif _, ok := jobs[jobID]; ok {\n\t\t\t\tduplicateJobIDs = true\n\t\t\t} else {\n\t\t\t\tjobs[jobID] = true\n\t\t\t}\n\t\t\tlineInfos = append(lineInfos, line)\n\t\t\tif jobIDMaxWidth < len(line.jobID) {\n\t\t\t\tjobIDMaxWidth = len(line.jobID)\n\t\t\t}\n\t\t\tif jobNameMaxWidth < len(line.jobName) {\n\t\t\t\tjobNameMaxWidth = len(line.jobName)\n\t\t\t}\n\t\t\tif stageMaxWidth < len(line.stage) {\n\t\t\t\tstageMaxWidth = len(line.stage)\n\t\t\t}\n\t\t\tif wfNameMaxWidth < len(line.wfName) {\n\t\t\t\twfNameMaxWidth = len(line.wfName)\n\t\t\t}\n\t\t\tif wfFileMaxWidth < len(line.wfFile) {\n\t\t\t\twfFileMaxWidth = len(line.wfFile)\n\t\t\t}\n\t\t\tif eventsMaxWidth < len(line.events) {\n\t\t\t\teventsMaxWidth = len(line.events)\n\t\t\t}\n\t\t}\n\t}\n\n\tjobIDMaxWidth += 2\n\tjobNameMaxWidth += 2\n\tstageMaxWidth += 2\n\twfNameMaxWidth += 2\n\twfFileMaxWidth += 2\n\n\tfmt.Printf(\"%*s%*s%*s%*s%*s%*s\\n\",\n\t\t-stageMaxWidth, header.stage,\n\t\t-jobIDMaxWidth, header.jobID,\n\t\t-jobNameMaxWidth, header.jobName,\n\t\t-wfNameMaxWidth, header.wfName,\n\t\t-wfFileMaxWidth, header.wfFile,\n\t\t-eventsMaxWidth, header.events,\n\t)\n\tfor _, line := range lineInfos {\n\t\tfmt.Printf(\"%*s%*s%*s%*s%*s%*s\\n\",\n\t\t\t-stageMaxWidth, line.stage,\n\t\t\t-jobIDMaxWidth, line.jobID,\n\t\t\t-jobNameMaxWidth, line.jobName,\n\t\t\t-wfNameMaxWidth, line.wfName,\n\t\t\t-wfFileMaxWidth, line.wfFile,\n\t\t\t-eventsMaxWidth, line.events,\n\t\t)\n\t}\n\tif duplicateJobIDs {\n\t\tfmt.Print(\"\\nDetected multiple jobs with the same job name, use `-W` to specify the path to the specific workflow.\\n\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/notices.go",
    "content": "package cmd\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype Notice struct {\n\tLevel   string `json:\"level\"`\n\tMessage string `json:\"message\"`\n}\n\nfunc displayNotices(input *Input) {\n\t// Avoid causing trouble parsing the json\n\tif input.listOptions {\n\t\treturn\n\t}\n\tselect {\n\tcase notices := <-noticesLoaded:\n\t\tif len(notices) > 0 {\n\t\t\tnoticeLogger := log.New()\n\t\t\tif input.jsonLogger {\n\t\t\t\tnoticeLogger.SetFormatter(&log.JSONFormatter{})\n\t\t\t} else {\n\t\t\t\tnoticeLogger.SetFormatter(&log.TextFormatter{\n\t\t\t\t\tDisableQuote:     true,\n\t\t\t\t\tDisableTimestamp: true,\n\t\t\t\t\tPadLevelText:     true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfmt.Printf(\"\\n\")\n\t\t\tfor _, notice := range notices {\n\t\t\t\tlevel, err := log.ParseLevel(notice.Level)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlevel = log.InfoLevel\n\t\t\t\t}\n\t\t\t\tnoticeLogger.Log(level, notice.Message)\n\t\t\t}\n\t\t}\n\tcase <-time.After(time.Second * 1):\n\t\tlog.Debugf(\"Timeout waiting for notices\")\n\t}\n}\n\nvar noticesLoaded = make(chan []Notice)\n\nfunc loadVersionNotices(version string) {\n\tgo func() {\n\t\tnoticesLoaded <- getVersionNotices(version)\n\t}()\n}\n\nconst NoticeURL = \"https://api.nektosact.com/notices\"\n\nfunc getVersionNotices(version string) []Notice {\n\tif os.Getenv(\"ACT_DISABLE_VERSION_CHECK\") == \"1\" {\n\t\treturn nil\n\t}\n\n\tnoticeURL, err := url.Parse(NoticeURL)\n\tif err != nil {\n\t\tlog.Error(err)\n\t\treturn nil\n\t}\n\tquery := noticeURL.Query()\n\tquery.Add(\"os\", runtime.GOOS)\n\tquery.Add(\"arch\", runtime.GOARCH)\n\tquery.Add(\"version\", version)\n\n\tnoticeURL.RawQuery = query.Encode()\n\n\tclient := &http.Client{}\n\treq, err := http.NewRequest(\"GET\", noticeURL.String(), nil)\n\tif err != nil {\n\t\tlog.Debug(err)\n\t\treturn nil\n\t}\n\n\tetag := loadNoticesEtag()\n\tif etag != \"\" {\n\t\tlog.Debugf(\"Conditional GET for notices etag=%s\", etag)\n\t\treq.Header.Set(\"If-None-Match\", etag)\n\t}\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tlog.Debug(err)\n\t\treturn nil\n\t}\n\n\tnewEtag := resp.Header.Get(\"Etag\")\n\tif newEtag != \"\" {\n\t\tlog.Debugf(\"Saving notices etag=%s\", newEtag)\n\t\tsaveNoticesEtag(newEtag)\n\t}\n\n\tdefer resp.Body.Close()\n\tnotices := []Notice{}\n\tif resp.StatusCode == 304 {\n\t\tlog.Debug(\"No new notices\")\n\t\treturn nil\n\t}\n\tif err := json.NewDecoder(resp.Body).Decode(&notices); err != nil {\n\t\tlog.Debug(err)\n\t\treturn nil\n\t}\n\n\treturn notices\n}\n\nfunc loadNoticesEtag() string {\n\tp := etagPath()\n\tcontent, err := os.ReadFile(p)\n\tif err != nil {\n\t\tlog.Debugf(\"Unable to load etag from %s: %e\", p, err)\n\t}\n\treturn strings.TrimSuffix(string(content), \"\\n\")\n}\n\nfunc saveNoticesEtag(etag string) {\n\tp := etagPath()\n\terr := os.WriteFile(p, []byte(strings.TrimSuffix(etag, \"\\n\")), 0o600)\n\tif err != nil {\n\t\tlog.Debugf(\"Unable to save etag to %s: %e\", p, err)\n\t}\n}\n\nfunc etagPath() string {\n\tdir := filepath.Join(CacheHomeDir, \"act\")\n\tif err := os.MkdirAll(dir, 0o777); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\treturn filepath.Join(dir, \".notices.etag\")\n}\n"
  },
  {
    "path": "cmd/platforms.go",
    "content": "package cmd\n\nimport (\n\t\"strings\"\n)\n\nfunc (i *Input) newPlatforms() map[string]string {\n\tplatforms := map[string]string{\n\t\t\"ubuntu-latest\": \"node:16-buster-slim\",\n\t\t\"ubuntu-22.04\":  \"node:16-bullseye-slim\",\n\t\t\"ubuntu-20.04\":  \"node:16-buster-slim\",\n\t\t\"ubuntu-18.04\":  \"node:16-buster-slim\",\n\t}\n\n\tfor _, p := range i.platforms {\n\t\tpParts := strings.Split(p, \"=\")\n\t\tif len(pParts) == 2 {\n\t\t\tplatforms[strings.ToLower(pParts[0])] = pParts[1]\n\t\t}\n\t}\n\treturn platforms\n}\n"
  },
  {
    "path": "cmd/root.go",
    "content": "package cmd\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"strings\"\n\n\t\"github.com/AlecAivazis/survey/v2\"\n\t\"github.com/adrg/xdg\"\n\t\"github.com/andreaskoch/go-fswatch\"\n\tdocker_container \"github.com/docker/docker/api/types/container\"\n\t\"github.com/joho/godotenv\"\n\tgitignore \"github.com/sabhiram/go-gitignore\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/cobra/doc\"\n\t\"github.com/spf13/pflag\"\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/nektos/act/pkg/artifactcache\"\n\t\"github.com/nektos/act/pkg/artifacts\"\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/gh\"\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/nektos/act/pkg/runner\"\n)\n\ntype Flag struct {\n\tName        string `json:\"name\"`\n\tDefault     string `json:\"default\"`\n\tType        string `json:\"type\"`\n\tDescription string `json:\"description\"`\n}\n\nvar exitFunc = os.Exit\n\n// Execute is the entry point to running the CLI\nfunc Execute(ctx context.Context, version string) {\n\tinput := new(Input)\n\trootCmd := createRootCommand(ctx, input, version)\n\n\tif err := rootCmd.Execute(); err != nil {\n\t\texitFunc(1)\n\t}\n}\n\nfunc createRootCommand(ctx context.Context, input *Input, version string) *cobra.Command {\n\trootCmd := &cobra.Command{\n\t\tUse:               \"act [event name to run] [flags]\\n\\nIf no event name passed, will default to \\\"on: push\\\"\\nIf actions handles only one event it will be used as default instead of \\\"on: push\\\"\",\n\t\tShort:             \"Run GitHub actions locally by specifying the event name (e.g. `push`) or an action name directly.\",\n\t\tArgs:              cobra.MaximumNArgs(1),\n\t\tRunE:              newRunCommand(ctx, input),\n\t\tPersistentPreRun:  setup(input),\n\t\tPersistentPostRun: cleanup(input),\n\t\tVersion:           version,\n\t\tSilenceUsage:      true,\n\t}\n\n\trootCmd.Flags().BoolP(\"watch\", \"w\", false, \"watch the contents of the local repo and run when files change\")\n\trootCmd.Flags().BoolVar(&input.validate, \"validate\", false, \"validate workflows\")\n\trootCmd.Flags().BoolVar(&input.strict, \"strict\", false, \"use strict workflow schema\")\n\trootCmd.Flags().BoolP(\"list\", \"l\", false, \"list workflows\")\n\trootCmd.Flags().BoolP(\"graph\", \"g\", false, \"draw workflows\")\n\trootCmd.Flags().StringP(\"job\", \"j\", \"\", \"run a specific job ID\")\n\trootCmd.Flags().BoolP(\"bug-report\", \"\", false, \"Display system information for bug report\")\n\trootCmd.Flags().BoolP(\"man-page\", \"\", false, \"Print a generated manual page to stdout\")\n\n\trootCmd.Flags().StringVar(&input.remoteName, \"remote-name\", \"origin\", \"git remote name that will be used to retrieve url of git repo\")\n\trootCmd.Flags().StringArrayVarP(&input.secrets, \"secret\", \"s\", []string{}, \"secret to make available to actions with optional value (e.g. -s mysecret=foo or -s mysecret)\")\n\trootCmd.Flags().StringArrayVar(&input.vars, \"var\", []string{}, \"variable to make available to actions with optional value (e.g. --var myvar=foo or --var myvar)\")\n\trootCmd.Flags().StringArrayVarP(&input.envs, \"env\", \"\", []string{}, \"env to make available to actions with optional value (e.g. --env myenv=foo or --env myenv)\")\n\trootCmd.Flags().StringArrayVarP(&input.inputs, \"input\", \"\", []string{}, \"action input to make available to actions (e.g. --input myinput=foo)\")\n\trootCmd.Flags().StringArrayVarP(&input.platforms, \"platform\", \"P\", []string{}, \"custom image to use per platform (e.g. -P ubuntu-18.04=nektos/act-environments-ubuntu:18.04)\")\n\trootCmd.Flags().BoolVarP(&input.reuseContainers, \"reuse\", \"r\", false, \"don't remove container(s) on successfully completed workflow(s) to maintain state between runs\")\n\trootCmd.Flags().BoolVarP(&input.bindWorkdir, \"bind\", \"b\", false, \"bind working directory to container, rather than copy\")\n\trootCmd.Flags().BoolVarP(&input.forcePull, \"pull\", \"p\", true, \"pull docker image(s) even if already present\")\n\trootCmd.Flags().BoolVarP(&input.forceRebuild, \"rebuild\", \"\", true, \"rebuild local action docker image(s) even if already present\")\n\trootCmd.Flags().BoolVarP(&input.autodetectEvent, \"detect-event\", \"\", false, \"Use first event type from workflow as event that triggered the workflow\")\n\trootCmd.Flags().StringVarP(&input.eventPath, \"eventpath\", \"e\", \"\", \"path to event JSON file\")\n\trootCmd.Flags().StringVar(&input.defaultBranch, \"defaultbranch\", \"\", \"the name of the main branch\")\n\trootCmd.Flags().BoolVar(&input.privileged, \"privileged\", false, \"use privileged mode\")\n\trootCmd.Flags().StringVar(&input.usernsMode, \"userns\", \"\", \"user namespace to use\")\n\trootCmd.Flags().BoolVar(&input.useGitIgnore, \"use-gitignore\", true, \"Controls whether paths specified in .gitignore should be copied into container\")\n\trootCmd.Flags().StringArrayVarP(&input.containerCapAdd, \"container-cap-add\", \"\", []string{}, \"kernel capabilities to add to the workflow containers (e.g. --container-cap-add SYS_PTRACE)\")\n\trootCmd.Flags().StringArrayVarP(&input.containerCapDrop, \"container-cap-drop\", \"\", []string{}, \"kernel capabilities to remove from the workflow containers (e.g. --container-cap-drop SYS_PTRACE)\")\n\trootCmd.Flags().BoolVar(&input.autoRemove, \"rm\", false, \"automatically remove container(s)/volume(s) after a workflow(s) failure\")\n\trootCmd.Flags().StringArrayVarP(&input.replaceGheActionWithGithubCom, \"replace-ghe-action-with-github-com\", \"\", []string{}, \"If you are using GitHub Enterprise Server and allow specified actions from GitHub (github.com), you can set actions on this. (e.g. --replace-ghe-action-with-github-com =github/super-linter)\")\n\trootCmd.Flags().StringVar(&input.replaceGheActionTokenWithGithubCom, \"replace-ghe-action-token-with-github-com\", \"\", \"If you are using replace-ghe-action-with-github-com  and you want to use private actions on GitHub, you have to set personal access token\")\n\trootCmd.Flags().StringArrayVarP(&input.matrix, \"matrix\", \"\", []string{}, \"specify which matrix configuration to include (e.g. --matrix java:13\")\n\trootCmd.PersistentFlags().StringVarP(&input.actor, \"actor\", \"a\", \"nektos/act\", \"user that triggered the event\")\n\trootCmd.PersistentFlags().StringVarP(&input.workflowsPath, \"workflows\", \"W\", \"./.github/workflows/\", \"path to workflow file(s)\")\n\trootCmd.PersistentFlags().BoolVarP(&input.noWorkflowRecurse, \"no-recurse\", \"\", false, \"Flag to disable running workflows from subdirectories of specified path in '--workflows'/'-W' flag\")\n\trootCmd.PersistentFlags().StringVarP(&input.workdir, \"directory\", \"C\", \".\", \"working directory\")\n\trootCmd.PersistentFlags().BoolP(\"verbose\", \"v\", false, \"verbose output\")\n\trootCmd.PersistentFlags().BoolVar(&input.jsonLogger, \"json\", false, \"Output logs in json format\")\n\trootCmd.PersistentFlags().BoolVar(&input.logPrefixJobID, \"log-prefix-job-id\", false, \"Output the job id within non-json logs instead of the entire name\")\n\trootCmd.PersistentFlags().BoolVarP(&input.noOutput, \"quiet\", \"q\", false, \"disable logging of output from steps\")\n\trootCmd.PersistentFlags().BoolVarP(&input.dryrun, \"dryrun\", \"n\", false, \"disable container creation, validates only workflow correctness\")\n\trootCmd.PersistentFlags().StringVarP(&input.secretfile, \"secret-file\", \"\", \".secrets\", \"file with list of secrets to read from (e.g. --secret-file .secrets)\")\n\trootCmd.PersistentFlags().StringVarP(&input.varfile, \"var-file\", \"\", \".vars\", \"file with list of vars to read from (e.g. --var-file .vars)\")\n\trootCmd.PersistentFlags().BoolVarP(&input.insecureSecrets, \"insecure-secrets\", \"\", false, \"NOT RECOMMENDED! Doesn't hide secrets while printing logs.\")\n\trootCmd.PersistentFlags().StringVarP(&input.envfile, \"env-file\", \"\", \".env\", \"environment file to read and use as env in the containers\")\n\trootCmd.PersistentFlags().StringVarP(&input.inputfile, \"input-file\", \"\", \".input\", \"input file to read and use as action input\")\n\trootCmd.PersistentFlags().StringVarP(&input.containerArchitecture, \"container-architecture\", \"\", \"\", \"Architecture which should be used to run containers, e.g.: linux/amd64. If not specified, will use host default architecture. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.\")\n\trootCmd.PersistentFlags().StringVarP(&input.containerDaemonSocket, \"container-daemon-socket\", \"\", \"\", \"URI to Docker Engine socket (e.g.: unix://~/.docker/run/docker.sock or - to disable bind mounting the socket)\")\n\trootCmd.PersistentFlags().StringVarP(&input.containerOptions, \"container-options\", \"\", \"\", \"Custom docker container options for the job container without an options property in the job definition\")\n\trootCmd.PersistentFlags().StringVarP(&input.githubInstance, \"github-instance\", \"\", \"github.com\", \"GitHub instance to use. Only use this when using GitHub Enterprise Server.\")\n\trootCmd.PersistentFlags().StringVarP(&input.artifactServerPath, \"artifact-server-path\", \"\", \"\", \"Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.\")\n\trootCmd.PersistentFlags().StringVarP(&input.artifactServerAddr, \"artifact-server-addr\", \"\", common.GetOutboundIP().String(), \"Defines the address to which the artifact server binds.\")\n\trootCmd.PersistentFlags().StringVarP(&input.artifactServerPort, \"artifact-server-port\", \"\", \"34567\", \"Defines the port where the artifact server listens.\")\n\trootCmd.PersistentFlags().BoolVarP(&input.noSkipCheckout, \"no-skip-checkout\", \"\", false, \"Use actions/checkout instead of copying local files into container\")\n\trootCmd.PersistentFlags().BoolVarP(&input.noCacheServer, \"no-cache-server\", \"\", false, \"Disable cache server\")\n\trootCmd.PersistentFlags().StringVarP(&input.cacheServerPath, \"cache-server-path\", \"\", filepath.Join(CacheHomeDir, \"actcache\"), \"Defines the path where the cache server stores caches.\")\n\trootCmd.PersistentFlags().StringVarP(&input.cacheServerExternalURL, \"cache-server-external-url\", \"\", \"\", \"Defines the external URL for if the cache server is behind a proxy. e.g.: https://act-cache-server.example.com. Be careful that there is no trailing slash.\")\n\trootCmd.PersistentFlags().StringVarP(&input.cacheServerAddr, \"cache-server-addr\", \"\", common.GetOutboundIP().String(), \"Defines the address to which the cache server binds.\")\n\trootCmd.PersistentFlags().Uint16VarP(&input.cacheServerPort, \"cache-server-port\", \"\", 0, \"Defines the port where the artifact server listens. 0 means a randomly available port.\")\n\trootCmd.PersistentFlags().StringVarP(&input.actionCachePath, \"action-cache-path\", \"\", filepath.Join(CacheHomeDir, \"act\"), \"Defines the path where the actions get cached and host workspaces created.\")\n\trootCmd.PersistentFlags().BoolVarP(&input.actionOfflineMode, \"action-offline-mode\", \"\", false, \"If action contents exists, it will not be fetch and pull again. If turn on this, will turn off force pull\")\n\trootCmd.PersistentFlags().StringVarP(&input.networkName, \"network\", \"\", \"host\", \"Sets a docker network name. Defaults to host.\")\n\trootCmd.PersistentFlags().BoolVarP(&input.useNewActionCache, \"use-new-action-cache\", \"\", false, \"Enable using the new Action Cache for storing Actions locally\")\n\trootCmd.PersistentFlags().StringArrayVarP(&input.localRepository, \"local-repository\", \"\", []string{}, \"Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols)\")\n\trootCmd.PersistentFlags().BoolVar(&input.listOptions, \"list-options\", false, \"Print a json structure of compatible options\")\n\trootCmd.PersistentFlags().IntVar(&input.concurrentJobs, \"concurrent-jobs\", 0, \"Maximum number of concurrent jobs to run. Default is the number of CPUs available.\")\n\trootCmd.SetArgs(args())\n\treturn rootCmd\n}\n\n// Return locations where Act's config can be found in order: XDG spec, .actrc in HOME directory, .actrc in invocation directory\nfunc configLocations() []string {\n\tconfigFileName := \".actrc\"\n\n\thomePath := filepath.Join(UserHomeDir, configFileName)\n\tinvocationPath := filepath.Join(\".\", configFileName)\n\n\t// Though named xdg, adrg's lib support macOS and Windows config paths as well\n\t// It also takes cares of creating the parent folder so we don't need to bother later\n\tspecPath, err := xdg.ConfigFile(\"act/actrc\")\n\tif err != nil {\n\t\tspecPath = homePath\n\t}\n\n\t// This order should be enforced since the survey part relies on it\n\treturn []string{specPath, homePath, invocationPath}\n}\n\nfunc args() []string {\n\tactrc := configLocations()\n\n\targs := make([]string, 0)\n\tfor _, f := range actrc {\n\t\targs = append(args, readArgsFile(f, true)...)\n\t}\n\n\targs = append(args, os.Args[1:]...)\n\treturn args\n}\n\nfunc bugReport(ctx context.Context, version string) error {\n\tsprintf := func(key, val string) string {\n\t\treturn fmt.Sprintf(\"%-24s%s\\n\", key, val)\n\t}\n\n\treport := sprintf(\"act version:\", version)\n\treport += sprintf(\"GOOS:\", runtime.GOOS)\n\treport += sprintf(\"GOARCH:\", runtime.GOARCH)\n\treport += sprintf(\"NumCPU:\", fmt.Sprint(runtime.NumCPU()))\n\n\tvar dockerHost string\n\tvar exists bool\n\tif dockerHost, exists = os.LookupEnv(\"DOCKER_HOST\"); !exists {\n\t\tdockerHost = \"DOCKER_HOST environment variable is not set\"\n\t} else if dockerHost == \"\" {\n\t\tdockerHost = \"DOCKER_HOST environment variable is empty.\"\n\t}\n\n\treport += sprintf(\"Docker host:\", dockerHost)\n\treport += fmt.Sprintln(\"Sockets found:\")\n\tfor _, p := range container.CommonSocketLocations {\n\t\tif _, err := os.Lstat(os.ExpandEnv(p)); err != nil {\n\t\t\tcontinue\n\t\t} else if _, err := os.Stat(os.ExpandEnv(p)); err != nil {\n\t\t\treport += fmt.Sprintf(\"\\t%s(broken)\\n\", p)\n\t\t} else {\n\t\t\treport += fmt.Sprintf(\"\\t%s\\n\", p)\n\t\t}\n\t}\n\n\treport += sprintf(\"Config files:\", \"\")\n\tfor _, c := range configLocations() {\n\t\targs := readArgsFile(c, false)\n\t\tif len(args) > 0 {\n\t\t\treport += fmt.Sprintf(\"\\t%s:\\n\", c)\n\t\t\tfor _, l := range args {\n\t\t\t\treport += fmt.Sprintf(\"\\t\\t%s\\n\", l)\n\t\t\t}\n\t\t}\n\t}\n\n\tvcs, ok := debug.ReadBuildInfo()\n\tif ok && vcs != nil {\n\t\treport += fmt.Sprintln(\"Build info:\")\n\t\tvcs := *vcs\n\t\treport += sprintf(\"\\tGo version:\", vcs.GoVersion)\n\t\treport += sprintf(\"\\tModule path:\", vcs.Path)\n\t\treport += sprintf(\"\\tMain version:\", vcs.Main.Version)\n\t\treport += sprintf(\"\\tMain path:\", vcs.Main.Path)\n\t\treport += sprintf(\"\\tMain checksum:\", vcs.Main.Sum)\n\n\t\treport += fmt.Sprintln(\"\\tBuild settings:\")\n\t\tfor _, set := range vcs.Settings {\n\t\t\treport += sprintf(fmt.Sprintf(\"\\t\\t%s:\", set.Key), set.Value)\n\t\t}\n\t}\n\n\tinfo, err := container.GetHostInfo(ctx)\n\tif err != nil {\n\t\tfmt.Println(report)\n\t\treturn err\n\t}\n\n\treport += fmt.Sprintln(\"Docker Engine:\")\n\n\treport += sprintf(\"\\tEngine version:\", info.ServerVersion)\n\treport += sprintf(\"\\tEngine runtime:\", info.DefaultRuntime)\n\treport += sprintf(\"\\tCgroup version:\", info.CgroupVersion)\n\treport += sprintf(\"\\tCgroup driver:\", info.CgroupDriver)\n\treport += sprintf(\"\\tStorage driver:\", info.Driver)\n\treport += sprintf(\"\\tRegistry URI:\", info.IndexServerAddress)\n\n\treport += sprintf(\"\\tOS:\", info.OperatingSystem)\n\treport += sprintf(\"\\tOS type:\", info.OSType)\n\treport += sprintf(\"\\tOS version:\", info.OSVersion)\n\treport += sprintf(\"\\tOS arch:\", info.Architecture)\n\treport += sprintf(\"\\tOS kernel:\", info.KernelVersion)\n\treport += sprintf(\"\\tOS CPU:\", fmt.Sprint(info.NCPU))\n\treport += sprintf(\"\\tOS memory:\", fmt.Sprintf(\"%d MB\", info.MemTotal/1024/1024))\n\n\treport += fmt.Sprintln(\"\\tSecurity options:\")\n\tfor _, secopt := range info.SecurityOptions {\n\t\treport += fmt.Sprintf(\"\\t\\t%s\\n\", secopt)\n\t}\n\n\tfmt.Println(report)\n\treturn nil\n}\n\nfunc generateManPage(cmd *cobra.Command) error {\n\theader := &doc.GenManHeader{\n\t\tTitle:   \"act\",\n\t\tSection: \"1\",\n\t\tSource:  fmt.Sprintf(\"act %s\", cmd.Version),\n\t}\n\tbuf := new(bytes.Buffer)\n\tcobra.CheckErr(doc.GenMan(cmd, header, buf))\n\tfmt.Print(buf.String())\n\treturn nil\n}\n\nfunc listOptions(cmd *cobra.Command) error {\n\tflags := []Flag{}\n\tcmd.LocalFlags().VisitAll(func(f *pflag.Flag) {\n\t\tflags = append(flags, Flag{Name: f.Name, Default: f.DefValue, Description: f.Usage, Type: f.Value.Type()})\n\t})\n\ta, err := json.Marshal(flags)\n\tfmt.Println(string(a))\n\treturn err\n}\n\nfunc readArgsFile(file string, split bool) []string {\n\targs := make([]string, 0)\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\treturn args\n\t}\n\tdefer func() {\n\t\terr := f.Close()\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"Failed to close args file: %v\", err)\n\t\t}\n\t}()\n\tscanner := bufio.NewScanner(f)\n\tscanner.Buffer(nil, 1024*1024*1024) // increase buffer to 1GB to avoid scanner buffer overflow\n\tfor scanner.Scan() {\n\t\targ := os.ExpandEnv(strings.TrimSpace(scanner.Text()))\n\n\t\tif strings.HasPrefix(arg, \"-\") && split {\n\t\t\targs = append(args, regexp.MustCompile(`\\s`).Split(arg, 2)...)\n\t\t} else if !split {\n\t\t\targs = append(args, arg)\n\t\t}\n\t}\n\treturn args\n}\n\nfunc setup(_ *Input) func(*cobra.Command, []string) {\n\treturn func(cmd *cobra.Command, _ []string) {\n\t\tverbose, _ := cmd.Flags().GetBool(\"verbose\")\n\t\tif verbose {\n\t\t\tlog.SetLevel(log.DebugLevel)\n\t\t}\n\t\tloadVersionNotices(cmd.Version)\n\t}\n}\n\nfunc cleanup(inputs *Input) func(*cobra.Command, []string) {\n\treturn func(_ *cobra.Command, _ []string) {\n\t\tdisplayNotices(inputs)\n\t}\n}\n\nfunc parseEnvs(env []string) map[string]string {\n\tenvs := make(map[string]string, len(env))\n\tfor _, envVar := range env {\n\t\te := strings.SplitN(envVar, `=`, 2)\n\t\tif len(e) == 2 {\n\t\t\tenvs[e[0]] = e[1]\n\t\t} else {\n\t\t\tenvs[e[0]] = \"\"\n\t\t}\n\t}\n\treturn envs\n}\n\nfunc readYamlFile(file string) (map[string]string, error) {\n\tcontent, err := os.ReadFile(file)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tret := map[string]string{}\n\tif err = yaml.Unmarshal(content, &ret); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ret, nil\n}\n\nfunc readEnvs(path string, envs map[string]string) bool {\n\treturn readEnvsEx(path, envs, false)\n}\n\nfunc readEnvsEx(path string, envs map[string]string, caseInsensitive bool) bool {\n\tif _, err := os.Stat(path); err == nil {\n\t\tvar env map[string]string\n\t\tif ext := filepath.Ext(path); ext == \".yml\" || ext == \".yaml\" {\n\t\t\tenv, err = readYamlFile(path)\n\t\t} else {\n\t\t\tenv, err = godotenv.Read(path)\n\t\t}\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Error loading from %s: %v\", path, err)\n\t\t}\n\t\tfor k, v := range env {\n\t\t\tif caseInsensitive {\n\t\t\t\tk = strings.ToUpper(k)\n\t\t\t}\n\t\t\tif _, ok := envs[k]; !ok {\n\t\t\t\tenvs[k] = v\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc parseMatrix(matrix []string) map[string]map[string]bool {\n\t// each matrix entry should be of the form - string:string\n\tr := regexp.MustCompile(\":\")\n\tmatrixes := make(map[string]map[string]bool)\n\tfor _, m := range matrix {\n\t\tmatrix := r.Split(m, 2)\n\t\tif len(matrix) < 2 {\n\t\t\tlog.Fatalf(\"Invalid matrix format. Failed to parse %s\", m)\n\t\t}\n\t\tif _, ok := matrixes[matrix[0]]; !ok {\n\t\t\tmatrixes[matrix[0]] = make(map[string]bool)\n\t\t}\n\t\tmatrixes[matrix[0]][matrix[1]] = true\n\t}\n\treturn matrixes\n}\n\n//nolint:gocyclo\nfunc newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []string) error {\n\treturn func(cmd *cobra.Command, args []string) error {\n\t\tif input.jsonLogger {\n\t\t\tlog.SetFormatter(&log.JSONFormatter{})\n\t\t}\n\n\t\tif ok, _ := cmd.Flags().GetBool(\"bug-report\"); ok {\n\t\t\tctx, cancel := common.EarlyCancelContext(ctx)\n\t\t\tdefer cancel()\n\t\t\treturn bugReport(ctx, cmd.Version)\n\t\t}\n\t\tif ok, _ := cmd.Flags().GetBool(\"man-page\"); ok {\n\t\t\treturn generateManPage(cmd)\n\t\t}\n\t\tif input.listOptions {\n\t\t\treturn listOptions(cmd)\n\t\t}\n\n\t\tif ret, err := container.GetSocketAndHost(input.containerDaemonSocket); err != nil {\n\t\t\tlog.Warnf(\"Couldn't get a valid docker connection: %+v\", err)\n\t\t} else {\n\t\t\tos.Setenv(\"DOCKER_HOST\", ret.Host)\n\t\t\tinput.containerDaemonSocket = ret.Socket\n\t\t\tlog.Infof(\"Using docker host '%s', and daemon socket '%s'\", ret.Host, ret.Socket)\n\t\t}\n\n\t\tif runtime.GOOS == \"darwin\" && runtime.GOARCH == \"arm64\" && input.containerArchitecture == \"\" {\n\t\t\tl := log.New()\n\t\t\tl.SetFormatter(&log.TextFormatter{\n\t\t\t\tDisableQuote:     true,\n\t\t\t\tDisableTimestamp: true,\n\t\t\t})\n\t\t\tl.Warnf(\" \\U000026A0 You are using Apple M-series chip and you have not specified container architecture, you might encounter issues while running act. If so, try running it with '--container-architecture linux/amd64'. \\U000026A0 \\n\")\n\t\t}\n\n\t\tlog.Debugf(\"Loading environment from %s\", input.Envfile())\n\t\tenvs := parseEnvs(input.envs)\n\t\t_ = readEnvs(input.Envfile(), envs)\n\n\t\tlog.Debugf(\"Loading action inputs from %s\", input.Inputfile())\n\t\tinputs := parseEnvs(input.inputs)\n\t\t_ = readEnvs(input.Inputfile(), inputs)\n\n\t\tlog.Debugf(\"Loading secrets from %s\", input.Secretfile())\n\t\tsecrets := newSecrets(input.secrets)\n\t\t_ = readEnvsEx(input.Secretfile(), secrets, true)\n\n\t\tif _, hasGitHubToken := secrets[\"GITHUB_TOKEN\"]; !hasGitHubToken {\n\t\t\tctx, cancel := common.EarlyCancelContext(ctx)\n\t\t\tdefer cancel()\n\t\t\tsecrets[\"GITHUB_TOKEN\"], _ = gh.GetToken(ctx, \"\")\n\t\t}\n\n\t\tlog.Debugf(\"Loading vars from %s\", input.Varfile())\n\t\tvars := newSecrets(input.vars)\n\t\t_ = readEnvs(input.Varfile(), vars)\n\n\t\tmatrixes := parseMatrix(input.matrix)\n\t\tlog.Debugf(\"Evaluated matrix inclusions: %v\", matrixes)\n\n\t\tplanner, err := model.NewWorkflowPlanner(input.WorkflowsPath(), input.noWorkflowRecurse, input.strict)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tjobID, err := cmd.Flags().GetString(\"job\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// check if we should just list the workflows\n\t\tlist, err := cmd.Flags().GetBool(\"list\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// check if we should just validate the workflows\n\t\tif input.validate {\n\t\t\treturn err\n\t\t}\n\n\t\t// check if we should just draw the graph\n\t\tgraph, err := cmd.Flags().GetBool(\"graph\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// collect all events from loaded workflows\n\t\tevents := planner.GetEvents()\n\n\t\t// plan with filtered jobs - to be used for filtering only\n\t\tvar filterPlan *model.Plan\n\n\t\t// Determine the event name to be filtered\n\t\tvar filterEventName string\n\n\t\tif len(args) > 0 {\n\t\t\tlog.Debugf(\"Using first passed in arguments event for filtering: %s\", args[0])\n\t\t\tfilterEventName = args[0]\n\t\t} else if input.autodetectEvent && len(events) > 0 && len(events[0]) > 0 {\n\t\t\t// set default event type to first event from many available\n\t\t\t// this way user dont have to specify the event.\n\t\t\tlog.Debugf(\"Using first detected workflow event for filtering: %s\", events[0])\n\t\t\tfilterEventName = events[0]\n\t\t}\n\n\t\tvar plannerErr error\n\t\tif jobID != \"\" {\n\t\t\tlog.Debugf(\"Preparing plan with a job: %s\", jobID)\n\t\t\tfilterPlan, plannerErr = planner.PlanJob(jobID)\n\t\t} else if filterEventName != \"\" {\n\t\t\tlog.Debugf(\"Preparing plan for a event: %s\", filterEventName)\n\t\t\tfilterPlan, plannerErr = planner.PlanEvent(filterEventName)\n\t\t} else {\n\t\t\tlog.Debugf(\"Preparing plan with all jobs\")\n\t\t\tfilterPlan, plannerErr = planner.PlanAll()\n\t\t}\n\t\tif filterPlan == nil && plannerErr != nil {\n\t\t\treturn plannerErr\n\t\t}\n\n\t\tif list {\n\t\t\terr = printList(filterPlan)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn plannerErr\n\t\t}\n\n\t\tif graph {\n\t\t\terr = drawGraph(filterPlan)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn plannerErr\n\t\t}\n\n\t\t// plan with triggered jobs\n\t\tvar plan *model.Plan\n\n\t\t// Determine the event name to be triggered\n\t\tvar eventName string\n\n\t\tif len(args) > 0 {\n\t\t\tlog.Debugf(\"Using first passed in arguments event: %s\", args[0])\n\t\t\teventName = args[0]\n\t\t} else if len(events) == 1 && len(events[0]) > 0 {\n\t\t\tlog.Debugf(\"Using the only detected workflow event: %s\", events[0])\n\t\t\teventName = events[0]\n\t\t} else if input.autodetectEvent && len(events) > 0 && len(events[0]) > 0 {\n\t\t\t// set default event type to first event from many available\n\t\t\t// this way user dont have to specify the event.\n\t\t\tlog.Debugf(\"Using first detected workflow event: %s\", events[0])\n\t\t\teventName = events[0]\n\t\t} else {\n\t\t\tlog.Debugf(\"Using default workflow event: push\")\n\t\t\teventName = \"push\"\n\t\t}\n\n\t\t// build the plan for this run\n\t\tif jobID != \"\" {\n\t\t\tlog.Debugf(\"Planning job: %s\", jobID)\n\t\t\tplan, plannerErr = planner.PlanJob(jobID)\n\t\t} else {\n\t\t\tlog.Debugf(\"Planning jobs for event: %s\", eventName)\n\t\t\tplan, plannerErr = planner.PlanEvent(eventName)\n\t\t}\n\t\tif plan != nil {\n\t\t\tif len(plan.Stages) == 0 {\n\t\t\t\tplannerErr = fmt.Errorf(\"Could not find any stages to run. View the valid jobs with `act --list`. Use `act --help` to find how to filter by Job ID/Workflow/Event Name\")\n\t\t\t}\n\t\t}\n\t\tif plan == nil && plannerErr != nil {\n\t\t\treturn plannerErr\n\t\t}\n\n\t\t// check to see if the main branch was defined\n\t\tdefaultbranch, err := cmd.Flags().GetString(\"defaultbranch\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Check if platforms flag is set, if not, run default image survey\n\t\tif len(input.platforms) == 0 {\n\t\t\tcfgFound := false\n\t\t\tcfgLocations := configLocations()\n\t\t\tfor _, v := range cfgLocations {\n\t\t\t\t_, err := os.Stat(v)\n\t\t\t\tif os.IsExist(err) {\n\t\t\t\t\tcfgFound = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !cfgFound && len(cfgLocations) > 0 {\n\t\t\t\t// The first config location refers to the global config folder one\n\t\t\t\tif err := defaultImageSurvey(cfgLocations[0]); err != nil {\n\t\t\t\t\tlog.Fatal(err)\n\t\t\t\t}\n\t\t\t\tinput.platforms = readArgsFile(cfgLocations[0], true)\n\t\t\t}\n\t\t}\n\t\tdeprecationWarning := \"--%s is deprecated and will be removed soon, please switch to cli: `--container-options \\\"%[2]s\\\"` or `.actrc`: `--container-options %[2]s`.\"\n\t\tif input.privileged {\n\t\t\tlog.Warnf(deprecationWarning, \"privileged\", \"--privileged\")\n\t\t}\n\t\tif len(input.usernsMode) > 0 {\n\t\t\tlog.Warnf(deprecationWarning, \"userns\", fmt.Sprintf(\"--userns=%s\", input.usernsMode))\n\t\t}\n\t\tif len(input.containerCapAdd) > 0 {\n\t\t\tlog.Warnf(deprecationWarning, \"container-cap-add\", fmt.Sprintf(\"--cap-add=%s\", input.containerCapAdd))\n\t\t}\n\t\tif len(input.containerCapDrop) > 0 {\n\t\t\tlog.Warnf(deprecationWarning, \"container-cap-drop\", fmt.Sprintf(\"--cap-drop=%s\", input.containerCapDrop))\n\t\t}\n\n\t\t// run the plan\n\t\tconfig := &runner.Config{\n\t\t\tActor:                              input.actor,\n\t\t\tEventName:                          eventName,\n\t\t\tEventPath:                          input.EventPath(),\n\t\t\tDefaultBranch:                      defaultbranch,\n\t\t\tForcePull:                          !input.actionOfflineMode && input.forcePull,\n\t\t\tForceRebuild:                       input.forceRebuild,\n\t\t\tReuseContainers:                    input.reuseContainers,\n\t\t\tWorkdir:                            input.Workdir(),\n\t\t\tActionCacheDir:                     input.actionCachePath,\n\t\t\tActionOfflineMode:                  input.actionOfflineMode,\n\t\t\tBindWorkdir:                        input.bindWorkdir,\n\t\t\tLogOutput:                          !input.noOutput,\n\t\t\tJSONLogger:                         input.jsonLogger,\n\t\t\tLogPrefixJobID:                     input.logPrefixJobID,\n\t\t\tEnv:                                envs,\n\t\t\tSecrets:                            secrets,\n\t\t\tVars:                               vars,\n\t\t\tInputs:                             inputs,\n\t\t\tToken:                              secrets[\"GITHUB_TOKEN\"],\n\t\t\tInsecureSecrets:                    input.insecureSecrets,\n\t\t\tPlatforms:                          input.newPlatforms(),\n\t\t\tPrivileged:                         input.privileged,\n\t\t\tUsernsMode:                         input.usernsMode,\n\t\t\tContainerArchitecture:              input.containerArchitecture,\n\t\t\tContainerDaemonSocket:              input.containerDaemonSocket,\n\t\t\tContainerOptions:                   input.containerOptions,\n\t\t\tUseGitIgnore:                       input.useGitIgnore,\n\t\t\tGitHubInstance:                     input.githubInstance,\n\t\t\tContainerCapAdd:                    input.containerCapAdd,\n\t\t\tContainerCapDrop:                   input.containerCapDrop,\n\t\t\tAutoRemove:                         input.autoRemove,\n\t\t\tArtifactServerPath:                 input.artifactServerPath,\n\t\t\tArtifactServerAddr:                 input.artifactServerAddr,\n\t\t\tArtifactServerPort:                 input.artifactServerPort,\n\t\t\tNoSkipCheckout:                     input.noSkipCheckout,\n\t\t\tRemoteName:                         input.remoteName,\n\t\t\tReplaceGheActionWithGithubCom:      input.replaceGheActionWithGithubCom,\n\t\t\tReplaceGheActionTokenWithGithubCom: input.replaceGheActionTokenWithGithubCom,\n\t\t\tMatrix:                             matrixes,\n\t\t\tContainerNetworkMode:               docker_container.NetworkMode(input.networkName),\n\t\t\tConcurrentJobs:                     input.concurrentJobs,\n\t\t}\n\t\tif input.useNewActionCache || len(input.localRepository) > 0 {\n\t\t\tif input.actionOfflineMode {\n\t\t\t\tconfig.ActionCache = &runner.GoGitActionCacheOfflineMode{\n\t\t\t\t\tParent: runner.GoGitActionCache{\n\t\t\t\t\t\tPath: config.ActionCacheDir,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconfig.ActionCache = &runner.GoGitActionCache{\n\t\t\t\t\tPath: config.ActionCacheDir,\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(input.localRepository) > 0 {\n\t\t\t\tlocalRepositories := map[string]string{}\n\t\t\t\tfor _, l := range input.localRepository {\n\t\t\t\t\tk, v, _ := strings.Cut(l, \"=\")\n\t\t\t\t\tlocalRepositories[k] = v\n\t\t\t\t}\n\t\t\t\tconfig.ActionCache = &runner.LocalRepositoryCache{\n\t\t\t\t\tParent:            config.ActionCache,\n\t\t\t\t\tLocalRepositories: localRepositories,\n\t\t\t\t\tCacheDirCache:     map[string]string{},\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tr, err := runner.New(config)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcancel := artifacts.Serve(ctx, input.artifactServerPath, input.artifactServerAddr, input.artifactServerPort)\n\n\t\tconst cacheURLKey = \"ACTIONS_CACHE_URL\"\n\t\tvar cacheHandler *artifactcache.Handler\n\t\tif !input.noCacheServer && envs[cacheURLKey] == \"\" {\n\t\t\tvar err error\n\t\t\tcacheHandler, err = artifactcache.StartHandler(input.cacheServerPath, input.cacheServerExternalURL, input.cacheServerAddr, input.cacheServerPort, common.Logger(ctx))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tenvs[cacheURLKey] = cacheHandler.ExternalURL() + \"/\"\n\t\t}\n\n\t\tctx = common.WithDryrun(ctx, input.dryrun)\n\t\tif watch, err := cmd.Flags().GetBool(\"watch\"); err != nil {\n\t\t\treturn err\n\t\t} else if watch {\n\t\t\terr = watchAndRun(ctx, r.NewPlanExecutor(plan))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn plannerErr\n\t\t}\n\n\t\texecutor := r.NewPlanExecutor(plan).Finally(func(_ context.Context) error {\n\t\t\tcancel()\n\t\t\t_ = cacheHandler.Close()\n\t\t\treturn nil\n\t\t})\n\t\terr = executor(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn plannerErr\n\t}\n}\n\nfunc defaultImageSurvey(actrc string) error {\n\tvar answer string\n\tconfirmation := &survey.Select{\n\t\tMessage: \"Please choose the default image you want to use with act:\\n  - Large size image: ca. 17GB download + 53.1GB storage, you will need 75GB of free disk space, snapshots of GitHub Hosted Runners without snap and pulled docker images\\n  - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with most actions\\n  - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions\\n\\nDefault image and other options can be changed manually in \" + configLocations()[0] + \" (please refer to https://nektosact.com/usage/index.html?highlight=configur#configuration-file for additional information about file structure)\",\n\t\tHelp:    \"If you want to know why act asks you that, please go to https://github.com/nektos/act/issues/107\",\n\t\tDefault: \"Medium\",\n\t\tOptions: []string{\"Large\", \"Medium\", \"Micro\"},\n\t}\n\n\terr := survey.AskOne(confirmation, &answer)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar option string\n\tswitch answer {\n\tcase \"Large\":\n\t\toption = \"-P ubuntu-latest=catthehacker/ubuntu:full-latest\\n-P ubuntu-22.04=catthehacker/ubuntu:full-22.04\\n-P ubuntu-20.04=catthehacker/ubuntu:full-20.04\\n-P ubuntu-18.04=catthehacker/ubuntu:full-18.04\\n\"\n\tcase \"Medium\":\n\t\toption = \"-P ubuntu-latest=catthehacker/ubuntu:act-latest\\n-P ubuntu-22.04=catthehacker/ubuntu:act-22.04\\n-P ubuntu-20.04=catthehacker/ubuntu:act-20.04\\n-P ubuntu-18.04=catthehacker/ubuntu:act-18.04\\n\"\n\tcase \"Micro\":\n\t\toption = \"-P ubuntu-latest=node:16-buster-slim\\n-P ubuntu-22.04=node:16-bullseye-slim\\n-P ubuntu-20.04=node:16-buster-slim\\n-P ubuntu-18.04=node:16-buster-slim\\n\"\n\t}\n\n\tf, err := os.Create(actrc)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = f.WriteString(option)\n\tif err != nil {\n\t\t_ = f.Close()\n\t\treturn err\n\t}\n\n\terr = f.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc watchAndRun(ctx context.Context, fn common.Executor) error {\n\tdir, err := os.Getwd()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tignoreFile := filepath.Join(dir, \".gitignore\")\n\tignore := &gitignore.GitIgnore{}\n\tif info, err := os.Stat(ignoreFile); err == nil && !info.IsDir() {\n\t\tignore, err = gitignore.CompileIgnoreFile(ignoreFile)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"compile %q: %w\", ignoreFile, err)\n\t\t}\n\t}\n\n\tfolderWatcher := fswatch.NewFolderWatcher(\n\t\tdir,\n\t\ttrue,\n\t\tignore.MatchesPath,\n\t\t2, // 2 seconds\n\t)\n\n\tfolderWatcher.Start()\n\tdefer folderWatcher.Stop()\n\n\t// run once before watching\n\tif err := fn(ctx); err != nil {\n\t\treturn err\n\t}\n\n\tearlyCancelCtx, cancel := common.EarlyCancelContext(ctx)\n\tdefer cancel()\n\n\tfor folderWatcher.IsRunning() {\n\t\tlog.Debugf(\"Watching %s for changes\", dir)\n\t\tselect {\n\t\tcase <-earlyCancelCtx.Done():\n\t\t\treturn nil\n\t\tcase changes := <-folderWatcher.ChangeDetails():\n\t\t\tlog.Debugf(\"%s\", changes.String())\n\t\t\tif err := fn(ctx); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/root_test.go",
    "content": "package cmd\n\nimport (\n\t\"context\"\n\t\"path\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestReadSecrets(t *testing.T) {\n\tsecrets := map[string]string{}\n\tret := readEnvsEx(path.Join(\"testdata\", \"secrets.yml\"), secrets, true)\n\tassert.True(t, ret)\n\tassert.Equal(t, `line1\nline2\nline3\n`, secrets[\"MYSECRET\"])\n}\n\nfunc TestReadEnv(t *testing.T) {\n\tsecrets := map[string]string{}\n\tret := readEnvs(path.Join(\"testdata\", \"secrets.yml\"), secrets)\n\tassert.True(t, ret)\n\tassert.Equal(t, `line1\nline2\nline3\n`, secrets[\"mysecret\"])\n}\n\nfunc TestListOptions(t *testing.T) {\n\trootCmd := createRootCommand(context.Background(), &Input{}, \"\")\n\terr := newRunCommand(context.Background(), &Input{\n\t\tlistOptions: true,\n\t})(rootCmd, []string{})\n\tassert.NoError(t, err)\n}\n\nfunc TestRun(t *testing.T) {\n\trootCmd := createRootCommand(context.Background(), &Input{}, \"\")\n\terr := newRunCommand(context.Background(), &Input{\n\t\tplatforms:     []string{\"ubuntu-latest=node:16-buster-slim\"},\n\t\tworkdir:       \"../pkg/runner/testdata/\",\n\t\tworkflowsPath: \"./basic/push.yml\",\n\t})(rootCmd, []string{})\n\tassert.NoError(t, err)\n}\n\nfunc TestRunPush(t *testing.T) {\n\trootCmd := createRootCommand(context.Background(), &Input{}, \"\")\n\terr := newRunCommand(context.Background(), &Input{\n\t\tplatforms:     []string{\"ubuntu-latest=node:16-buster-slim\"},\n\t\tworkdir:       \"../pkg/runner/testdata/\",\n\t\tworkflowsPath: \"./basic/push.yml\",\n\t})(rootCmd, []string{\"push\"})\n\tassert.NoError(t, err)\n}\n\nfunc TestRunPushJsonLogger(t *testing.T) {\n\trootCmd := createRootCommand(context.Background(), &Input{}, \"\")\n\terr := newRunCommand(context.Background(), &Input{\n\t\tplatforms:     []string{\"ubuntu-latest=node:16-buster-slim\"},\n\t\tworkdir:       \"../pkg/runner/testdata/\",\n\t\tworkflowsPath: \"./basic/push.yml\",\n\t\tjsonLogger:    true,\n\t})(rootCmd, []string{\"push\"})\n\tassert.NoError(t, err)\n}\n\nfunc TestFlags(t *testing.T) {\n\tfor _, f := range []string{\"graph\", \"list\", \"bug-report\", \"man-page\"} {\n\t\tt.Run(\"TestFlag-\"+f, func(t *testing.T) {\n\t\t\trootCmd := createRootCommand(context.Background(), &Input{}, \"\")\n\t\t\terr := rootCmd.Flags().Set(f, \"true\")\n\t\t\tassert.NoError(t, err)\n\t\t\terr = newRunCommand(context.Background(), &Input{\n\t\t\t\tplatforms:     []string{\"ubuntu-latest=node:16-buster-slim\"},\n\t\t\t\tworkdir:       \"../pkg/runner/testdata/\",\n\t\t\t\tworkflowsPath: \"./basic/push.yml\",\n\t\t\t})(rootCmd, []string{})\n\t\t\tassert.NoError(t, err)\n\t\t})\n\t}\n}\n\nfunc TestReadArgsFile(t *testing.T) {\n\ttables := []struct {\n\t\tpath  string\n\t\tsplit bool\n\t\targs  []string\n\t\tenv   map[string]string\n\t}{\n\t\t{\n\t\t\tpath:  path.Join(\"testdata\", \"simple.actrc\"),\n\t\t\tsplit: true,\n\t\t\targs:  []string{\"--container-architecture=linux/amd64\", \"--action-offline-mode\"},\n\t\t},\n\t\t{\n\t\t\tpath:  path.Join(\"testdata\", \"env.actrc\"),\n\t\t\tsplit: true,\n\t\t\tenv: map[string]string{\n\t\t\t\t\"FAKEPWD\": \"/fake/test/pwd\",\n\t\t\t\t\"FOO\":     \"foo\",\n\t\t\t},\n\t\t\targs: []string{\n\t\t\t\t\"--artifact-server-path\", \"/fake/test/pwd/.artifacts\",\n\t\t\t\t\"--env\", \"FOO=prefix/foo/suffix\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tpath:  path.Join(\"testdata\", \"split.actrc\"),\n\t\t\tsplit: true,\n\t\t\targs:  []string{\"--container-options\", \"--volume /foo:/bar --volume /baz:/qux --volume /tmp:/tmp\"},\n\t\t},\n\t}\n\tfor _, table := range tables {\n\t\tt.Run(table.path, func(t *testing.T) {\n\t\t\tfor k, v := range table.env {\n\t\t\t\tt.Setenv(k, v)\n\t\t\t}\n\t\t\targs := readArgsFile(table.path, table.split)\n\t\t\tassert.Equal(t, table.args, args)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/secrets.go",
    "content": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/term\"\n)\n\ntype secrets map[string]string\n\nfunc newSecrets(secretList []string) secrets {\n\ts := make(map[string]string)\n\tfor _, secretPair := range secretList {\n\t\tsecretPairParts := strings.SplitN(secretPair, \"=\", 2)\n\t\tsecretPairParts[0] = strings.ToUpper(secretPairParts[0])\n\t\tif strings.ToUpper(s[secretPairParts[0]]) == secretPairParts[0] {\n\t\t\tlog.Errorf(\"Secret %s is already defined (secrets are case insensitive)\", secretPairParts[0])\n\t\t}\n\t\tif len(secretPairParts) == 2 {\n\t\t\ts[secretPairParts[0]] = secretPairParts[1]\n\t\t} else if env, ok := os.LookupEnv(secretPairParts[0]); ok && env != \"\" {\n\t\t\ts[secretPairParts[0]] = env\n\t\t} else {\n\t\t\tfmt.Printf(\"Provide value for '%s': \", secretPairParts[0])\n\t\t\tval, err := term.ReadPassword(int(os.Stdin.Fd()))\n\t\t\tfmt.Println()\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"failed to read input: %v\", err)\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\t\ts[secretPairParts[0]] = string(val)\n\t\t}\n\t}\n\treturn s\n}\n\nfunc (s secrets) AsMap() map[string]string {\n\treturn s\n}\n"
  },
  {
    "path": "cmd/testdata/env.actrc",
    "content": "--artifact-server-path $FAKEPWD/.artifacts\n--env FOO=prefix/${FOO}/suffix\n"
  },
  {
    "path": "cmd/testdata/secrets.yml",
    "content": "mysecret: |\n  line1\n  line2\n  line3\n"
  },
  {
    "path": "cmd/testdata/simple.actrc",
    "content": "--container-architecture=linux/amd64\n--action-offline-mode\n"
  },
  {
    "path": "cmd/testdata/split.actrc",
    "content": "--container-options --volume /foo:/bar --volume /baz:/qux --volume /tmp:/tmp\n"
  },
  {
    "path": "codecov.yml",
    "content": "coverage:\n  status:\n    project:\n      default:\n        target: auto # auto compares coverage to the previous base commit\n        threshold: 1%\n    patch:\n      default:\n        target: 50%\n        informational: true\nignore:\n# Files generated by Google Protobuf do not require coverage\n- '**/*.pb.go'\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/nektos/act\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/AlecAivazis/survey/v2 v2.3.7\n\tgithub.com/Masterminds/semver v1.5.0\n\tgithub.com/adrg/xdg v0.5.3\n\tgithub.com/andreaskoch/go-fswatch v1.0.0\n\tgithub.com/creack/pty v1.1.24\n\tgithub.com/docker/cli v28.4.0+incompatible\n\tgithub.com/docker/docker v28.4.0+incompatible\n\tgithub.com/docker/go-connections v0.6.0\n\tgithub.com/go-git/go-billy/v5 v5.6.2\n\tgithub.com/go-git/go-git/v5 v5.16.5\n\tgithub.com/joho/godotenv v1.5.1\n\tgithub.com/julienschmidt/httprouter v1.3.0\n\tgithub.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51\n\tgithub.com/mattn/go-isatty v0.0.20\n\tgithub.com/moby/patternmatcher v0.6.0\n\tgithub.com/opencontainers/image-spec v1.1.1\n\tgithub.com/opencontainers/selinux v1.13.1\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/rhysd/actionlint v1.7.7\n\tgithub.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06\n\tgithub.com/sirupsen/logrus v1.9.3\n\tgithub.com/spf13/cobra v1.10.1\n\tgithub.com/spf13/pflag v1.0.9\n\tgithub.com/stretchr/testify v1.11.1\n\tgithub.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928\n\tgo.etcd.io/bbolt v1.4.3\n\tgolang.org/x/term v0.38.0\n\tgopkg.in/yaml.v3 v3.0.1\n\tgotest.tools/v3 v3.5.2\n)\n\nrequire (\n\tdario.cat/mergo v1.0.2\n\tgithub.com/containerd/errdefs v1.0.0\n\tgithub.com/distribution/reference v0.6.0\n\tgithub.com/golang-jwt/jwt/v5 v5.3.0\n\tgithub.com/moby/go-archive v0.1.0\n\tgoogle.golang.org/protobuf v1.36.9\n)\n\nrequire (\n\tgithub.com/Microsoft/go-winio v0.6.2 // indirect\n\tgithub.com/ProtonMail/go-crypto v1.1.6 // indirect\n\tgithub.com/bmatcuk/doublestar/v4 v4.8.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/cloudflare/circl v1.6.3 // indirect\n\tgithub.com/containerd/errdefs/pkg v0.3.0 // indirect\n\tgithub.com/containerd/log v0.1.0 // indirect\n\tgithub.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect\n\tgithub.com/cyphar/filepath-securejoin v0.5.1 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/docker/docker-credential-helpers v0.8.2 // indirect\n\tgithub.com/docker/go-units v0.5.0 // indirect\n\tgithub.com/emirpasic/gods v1.18.1 // indirect\n\tgithub.com/fatih/color v1.18.0 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-viper/mapstructure/v2 v2.4.0 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect\n\tgithub.com/google/go-cmp v0.7.0 // indirect\n\tgithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect\n\tgithub.com/kevinburke/ssh_config v1.2.0 // indirect\n\tgithub.com/klauspost/compress v1.18.0 // indirect\n\tgithub.com/mattn/go-colorable v0.1.14 // indirect\n\tgithub.com/mattn/go-runewidth v0.0.16 // indirect\n\tgithub.com/mattn/go-shellwords v1.0.12 // indirect\n\tgithub.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect\n\tgithub.com/moby/docker-image-spec v1.3.1 // indirect\n\tgithub.com/moby/sys/atomicwriter v0.1.0 // indirect\n\tgithub.com/moby/sys/sequential v0.6.0 // indirect\n\tgithub.com/moby/sys/user v0.4.0 // indirect\n\tgithub.com/moby/sys/userns v0.1.0 // indirect\n\tgithub.com/moby/term v0.5.0 // indirect\n\tgithub.com/morikuni/aec v1.0.0 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/pjbgf/sha1cd v0.3.2 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/rivo/uniseg v0.4.7 // indirect\n\tgithub.com/robfig/cron/v3 v3.0.1 // indirect\n\tgithub.com/russross/blackfriday/v2 v2.1.0 // indirect\n\tgithub.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect\n\tgithub.com/skeema/knownhosts v1.3.1 // indirect\n\tgithub.com/stretchr/objx v0.5.2 // indirect\n\tgithub.com/xanzy/ssh-agent v0.3.3 // indirect\n\tgithub.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect\n\tgithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect\n\tgithub.com/xeipuuv/gojsonschema v1.2.0 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect\n\tgo.opentelemetry.io/otel v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.40.0 // indirect\n\tgolang.org/x/crypto v0.46.0 // indirect\n\tgolang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect\n\tgolang.org/x/net v0.47.0 // indirect\n\tgolang.org/x/sync v0.19.0 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n\tgolang.org/x/text v0.32.0 // indirect\n\tgolang.org/x/time v0.6.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect\n\tgopkg.in/warnings.v0 v0.1.2 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=\ndario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=\ngithub.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=\ngithub.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=\ngithub.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=\ngithub.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=\ngithub.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=\ngithub.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=\ngithub.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=\ngithub.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=\ngithub.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=\ngithub.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=\ngithub.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=\ngithub.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=\ngithub.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=\ngithub.com/andreaskoch/go-fswatch v1.0.0 h1:la8nP/HiaFCxP2IM6NZNUCoxgLWuyNFgH0RligBbnJU=\ngithub.com/andreaskoch/go-fswatch v1.0.0/go.mod h1:r5/iV+4jfwoY2sYqBkg8vpF04ehOvEl4qPptVGdxmqo=\ngithub.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=\ngithub.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=\ngithub.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=\ngithub.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=\ngithub.com/bmatcuk/doublestar/v4 v4.8.0 h1:DSXtrypQddoug1459viM9X9D3dp1Z7993fw36I2kNcQ=\ngithub.com/bmatcuk/doublestar/v4 v4.8.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=\ngithub.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=\ngithub.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=\ngithub.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=\ngithub.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=\ngithub.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=\ngithub.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=\ngithub.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=\ngithub.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=\ngithub.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=\ngithub.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=\ngithub.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=\ngithub.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=\ngithub.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/docker/cli v28.4.0+incompatible h1:RBcf3Kjw2pMtwui5V0DIMdyeab8glEw5QY0UUU4C9kY=\ngithub.com/docker/cli v28.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/docker v28.4.0+incompatible h1:KVC7bz5zJY/4AZe/78BIvCnPsLaC9T/zh72xnlrTTOk=\ngithub.com/docker/docker v28.4.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=\ngithub.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=\ngithub.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=\ngithub.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=\ngithub.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=\ngithub.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=\ngithub.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=\ngithub.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=\ngithub.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=\ngithub.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=\ngithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=\ngithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=\ngithub.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=\ngithub.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=\ngithub.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=\ngithub.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=\ngithub.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=\ngithub.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=\ngithub.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=\ngithub.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=\ngithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=\ngithub.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=\ngithub.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=\ngithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=\ngithub.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=\ngithub.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=\ngithub.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=\ngithub.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=\ngithub.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=\ngithub.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=\ngithub.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=\ngithub.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=\ngithub.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=\ngithub.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=\ngithub.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=\ngithub.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=\ngithub.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=\ngithub.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=\ngithub.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=\ngithub.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=\ngithub.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=\ngithub.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=\ngithub.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=\ngithub.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=\ngithub.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=\ngithub.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=\ngithub.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=\ngithub.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=\ngithub.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=\ngithub.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=\ngithub.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=\ngithub.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=\ngithub.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=\ngithub.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=\ngithub.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=\ngithub.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=\ngithub.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=\ngithub.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=\ngithub.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=\ngithub.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=\ngithub.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rhysd/actionlint v1.7.7 h1:0KgkoNTrYY7vmOCs9BW2AHxLvvpoY9nEUzgBHiPUr0k=\ngithub.com/rhysd/actionlint v1.7.7/go.mod h1:AE6I6vJEkNaIfWqC2GNE5spIJNhxf8NCtLEKU4NnUXg=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=\ngithub.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=\ngithub.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=\ngithub.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=\ngithub.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=\ngithub.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=\ngithub.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=\ngithub.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=\ngithub.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=\ngithub.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=\ngithub.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=\ngithub.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=\ngithub.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928 h1:zjNCuOOhh1TKRU0Ru3PPPJt80z7eReswCao91gBLk00=\ngithub.com/timshannon/bolthold v0.0.0-20240314194003-30aac6950928/go.mod h1:PCFYfAEfKT+Nd6zWvUpsXduMR1bXFLf0uGSlEF05MCI=\ngithub.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=\ngithub.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=\ngithub.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=\ngithub.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngo.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=\ngo.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo=\ngo.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E=\ngo.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=\ngo.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=\ngo.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=\ngo.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=\ngo.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=\ngolang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=\ngolang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=\ngolang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=\ngolang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=\ngolang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=\ngolang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=\ngolang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=\ngolang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=\ngoogle.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=\ngoogle.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=\ngoogle.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=\ngoogle.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=\ngopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=\ngotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=\n"
  },
  {
    "path": "install.sh",
    "content": "#!/bin/sh\nset -e\n# Code originally generated by godownloader on 2021-12-22T16:10:52Z. DO NOT EDIT.\n# (godownloader is deprecated, so changes to this script are maintained in install.sh in https://github.com/nektos/act)\n#\n\nusage() {\n  this=$1\n  cat <<EOF\n$this: download go binaries for nektos/act\n\nUsage: $this [-b bindir] [-d] [-f] [tag]\n  -b sets bindir or installation directory, Defaults to ./bin\n  -d turns on debug logging\n  -f forces installation, bypassing version checks\n   [tag] is a tag from\n   https://github.com/nektos/act/releases\n   If tag is missing, then the latest will be used.\nEOF\n  exit 2\n}\n\nparse_args() {\n  #BINDIR is ./bin unless set be ENV\n  # over-ridden by flag below\n\n  BINDIR=${BINDIR:-./bin}\n  while getopts \"b:dfh?x\" arg; do\n    case \"$arg\" in\n      b) BINDIR=\"$OPTARG\" ;;\n      d) log_set_priority 10 ;;\n      f) FORCE_INSTALL=\"true\" ;;\n      h | \\?) usage \"$0\" ;;\n      x) set -x ;;\n    esac\n  done\n  shift $((OPTIND - 1))\n  TAG=$1\n}\n# this function wraps all the destructive operations\n# if a curl|bash cuts off the end of the script due to\n# network, either nothing will happen or will syntax error\n# out preventing half-done work\nexecute() {\n  tmpdir=$(mktemp -d)\n  log_debug \"downloading files into ${tmpdir}\"\n  http_download \"${tmpdir}/${TARBALL}\" \"${TARBALL_URL}\"\n  http_download \"${tmpdir}/${CHECKSUM}\" \"${CHECKSUM_URL}\"\n  hash_sha256_verify \"${tmpdir}/${TARBALL}\" \"${tmpdir}/${CHECKSUM}\"\n  srcdir=\"${tmpdir}\"\n  (cd \"${tmpdir}\" && untar \"${TARBALL}\")\n  test ! -d \"${BINDIR}\" && install -d \"${BINDIR}\"\n  for binexe in $BINARIES; do\n    if [ \"$OS\" = \"windows\" ]; then\n      binexe=\"${binexe}.exe\"\n    fi\n    install \"${srcdir}/${binexe}\" \"${BINDIR}/\"\n    log_info \"installed ${BINDIR}/${binexe}\"\n  done\n  rm -rf \"${tmpdir}\"\n}\nget_binaries() {\n  case \"$PLATFORM\" in\n    darwin/386) BINARIES=\"act\" ;;\n    darwin/amd64) BINARIES=\"act\" ;;\n    darwin/arm64) BINARIES=\"act\" ;;\n    darwin/armv6) BINARIES=\"act\" ;;\n    darwin/armv7) BINARIES=\"act\" ;;\n    linux/386) BINARIES=\"act\" ;;\n    linux/amd64) BINARIES=\"act\" ;;\n    linux/arm64) BINARIES=\"act\" ;;\n    linux/armv6) BINARIES=\"act\" ;;\n    linux/armv7) BINARIES=\"act\" ;;\n    windows/386) BINARIES=\"act\" ;;\n    windows/amd64) BINARIES=\"act\" ;;\n    windows/arm64) BINARIES=\"act\" ;;\n    windows/armv6) BINARIES=\"act\" ;;\n    windows/armv7) BINARIES=\"act\" ;;\n    *)\n      log_crit \"platform $PLATFORM is not supported.  Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new\"\n      exit 1\n      ;;\n  esac\n}\ntag_to_version() {\n  if [ -z \"${TAG}\" ]; then\n    log_info \"checking GitHub for latest tag\"\n  else\n    log_info \"checking GitHub for tag '${TAG}'\"\n  fi\n  REALTAG=$(github_release \"$OWNER/$REPO\" \"${TAG}\") && true\n  if test -z \"$REALTAG\"; then\n    log_crit \"unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details\"\n    exit 1\n  fi\n  # if version starts with 'v', remove it\n  TAG=\"$REALTAG\"\n  VERSION=${TAG#v}\n}\nadjust_format() {\n  # change format (tar.gz or zip) based on OS\n  case ${OS} in\n    windows) FORMAT=zip ;;\n  esac\n  true\n}\nadjust_os() {\n  # adjust archive name based on OS\n  case ${OS} in\n    386) OS=i386 ;;\n    amd64) OS=x86_64 ;;\n    darwin) OS=Darwin ;;\n    linux) OS=Linux ;;\n    windows) OS=Windows ;;\n  esac\n  true\n}\nadjust_arch() {\n  # adjust archive name based on ARCH\n  case ${ARCH} in\n    386) ARCH=i386 ;;\n    amd64) ARCH=x86_64 ;;\n    darwin) ARCH=Darwin ;;\n    linux) ARCH=Linux ;;\n    windows) ARCH=Windows ;;\n  esac\n  true\n}\ncheck_installed_version() {\n  # Check if force install flag is set\n  if [ \"${FORCE_INSTALL}\" = \"true\" ]; then\n    log_info \"force install enabled. Skipping version check.\"\n    return\n  fi\n\n  # Check if the binary exists\n  if is_command \"$BINARY\"; then\n    # Extract installed version using cut\n    INSTALLED_VERSION=$($BINARY --version | cut -d' ' -f3)\n\n    if [ -z \"$INSTALLED_VERSION\" ]; then\n      log_err \"failed to detect installed version. Proceeding with installation.\"\n      return\n    fi\n\n    log_info \"found installed version: $INSTALLED_VERSION\"\n\n    # Compare versions\n    if [ \"$INSTALLED_VERSION\" = \"$VERSION\" ]; then\n      log_info \"$BINARY version $INSTALLED_VERSION is already installed.\"\n      exit 0\n    else\n      log_debug \"updating $BINARY from version $INSTALLED_VERSION to $VERSION...\"\n    fi\n  else\n    log_debug \"$BINARY is not installed. Proceeding with installation...\"\n  fi\n}\n\n\ncat /dev/null <<EOF\n------------------------------------------------------------------------\nhttps://github.com/client9/shlib - portable posix shell functions\nPublic domain - http://unlicense.org\nhttps://github.com/client9/shlib/blob/master/LICENSE.md\nbut credit (and pull requests) appreciated.\n------------------------------------------------------------------------\nEOF\nis_command() {\n  command -v \"$1\" >/dev/null\n}\nechoerr() {\n  echo \"$@\" 1>&2\n}\nlog_prefix() {\n  echo \"$0\"\n}\n_logp=6\nlog_set_priority() {\n  _logp=\"$1\"\n}\nlog_priority() {\n  if test -z \"$1\"; then\n    echo \"$_logp\"\n    return\n  fi\n  [ \"$1\" -le \"$_logp\" ]\n}\nlog_tag() {\n  case $1 in\n    0) echo \"emerg\" ;;\n    1) echo \"alert\" ;;\n    2) echo \"crit\" ;;\n    3) echo \"err\" ;;\n    4) echo \"warning\" ;;\n    5) echo \"notice\" ;;\n    6) echo \"info\" ;;\n    7) echo \"debug\" ;;\n    *) echo \"$1\" ;;\n  esac\n}\nlog_debug() {\n  log_priority 7 || return 0\n  echoerr \"$(log_prefix)\" \"$(log_tag 7)\" \"$@\"\n}\nlog_info() {\n  log_priority 6 || return 0\n  echoerr \"$(log_prefix)\" \"$(log_tag 6)\" \"$@\"\n}\nlog_err() {\n  log_priority 3 || return 0\n  echoerr \"$(log_prefix)\" \"$(log_tag 3)\" \"$@\"\n}\nlog_crit() {\n  log_priority 2 || return 0\n  echoerr \"$(log_prefix)\" \"$(log_tag 2)\" \"$@\"\n}\nuname_os() {\n  os=$(uname -s | tr '[:upper:]' '[:lower:]')\n  case \"$os\" in\n    cygwin_nt*) os=\"windows\" ;;\n    mingw*) os=\"windows\" ;;\n    msys_nt*) os=\"windows\" ;;\n  esac\n  echo \"$os\"\n}\nuname_arch() {\n  arch=$(uname -m)\n  case $arch in\n    x86_64) arch=\"amd64\" ;;\n    x86) arch=\"386\" ;;\n    i686) arch=\"386\" ;;\n    i386) arch=\"386\" ;;\n    aarch64) arch=\"arm64\" ;;\n    armv5*) arch=\"armv5\" ;;\n    armv6*) arch=\"armv6\" ;;\n    armv7*) arch=\"armv7\" ;;\n  esac\n  echo ${arch}\n}\nuname_os_check() {\n  os=$(uname_os)\n  case \"$os\" in\n    darwin) return 0 ;;\n    dragonfly) return 0 ;;\n    freebsd) return 0 ;;\n    linux) return 0 ;;\n    android) return 0 ;;\n    nacl) return 0 ;;\n    netbsd) return 0 ;;\n    openbsd) return 0 ;;\n    plan9) return 0 ;;\n    solaris) return 0 ;;\n    windows) return 0 ;;\n  esac\n  log_crit \"uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib\"\n  return 1\n}\nuname_arch_check() {\n  arch=$(uname_arch)\n  case \"$arch\" in\n    386) return 0 ;;\n    amd64) return 0 ;;\n    arm64) return 0 ;;\n    armv5) return 0 ;;\n    armv6) return 0 ;;\n    armv7) return 0 ;;\n    ppc64) return 0 ;;\n    ppc64le) return 0 ;;\n    mips) return 0 ;;\n    mipsle) return 0 ;;\n    mips64) return 0 ;;\n    mips64le) return 0 ;;\n    s390x) return 0 ;;\n    amd64p32) return 0 ;;\n  esac\n  log_crit \"uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value.  Please file bug report at https://github.com/client9/shlib\"\n  return 1\n}\nuntar() {\n  tarball=$1\n  case \"${tarball}\" in\n    *.tar.gz | *.tgz) tar --no-same-owner -xzf \"${tarball}\" ;;\n    *.tar) tar --no-same-owner -xf \"${tarball}\" ;;\n    *.zip) unzip \"${tarball}\" ;;\n    *)\n      log_err \"untar unknown archive format for ${tarball}\"\n      return 1\n      ;;\n  esac\n}\nhttp_download_curl() {\n  local_file=$1\n  source_url=$2\n  header=$3\n  if [ -z \"$header\" ]; then\n    code=$(curl -w '%{http_code}' -sL -o \"$local_file\" \"$source_url\")\n  else\n    code=$(curl -w '%{http_code}' -sL -H \"$header\" -o \"$local_file\" \"$source_url\")\n  fi\n  if [ \"$code\" != \"200\" ]; then\n    log_debug \"http_download_curl received HTTP status $code\"\n    return 1\n  fi\n  return 0\n}\nhttp_download_wget() {\n  local_file=$1\n  source_url=$2\n  header=$3\n  if [ -z \"$header\" ]; then\n    wget -q -O \"$local_file\" \"$source_url\"\n  else\n    wget -q --header \"$header\" -O \"$local_file\" \"$source_url\"\n  fi\n}\nhttp_download() {\n  log_debug \"http_download $2\"\n  if is_command curl; then\n    http_download_curl \"$@\"\n    return\n  elif is_command wget; then\n    http_download_wget \"$@\"\n    return\n  fi\n  log_crit \"http_download unable to find wget or curl\"\n  return 1\n}\nhttp_copy() {\n  tmp=$(mktemp)\n  http_download \"${tmp}\" \"$1\" \"$2\" || return 1\n  body=$(cat \"$tmp\")\n  rm -f \"${tmp}\"\n  echo \"$body\"\n}\ngithub_release() {\n  owner_repo=$1\n  version=$2\n  test -z \"$version\" && version=\"latest\"\n  giturl=\"https://github.com/${owner_repo}/releases/${version}\"\n  json=$(http_copy \"$giturl\" \"Accept:application/json\")\n  test -z \"$json\" && return 1\n  version=$(echo \"$json\" | tr -s '\\n' ' ' | sed 's/.*\"tag_name\":\"//' | sed 's/\".*//')\n  test -z \"$version\" && return 1\n  echo \"$version\"\n}\nhash_sha256() {\n  TARGET=${1:-/dev/stdin}\n  if is_command gsha256sum; then\n    hash=$(gsha256sum \"$TARGET\") || return 1\n    echo \"$hash\" | cut -d ' ' -f 1\n  elif is_command sha256sum; then\n    hash=$(sha256sum \"$TARGET\") || return 1\n    echo \"$hash\" | cut -d ' ' -f 1\n  elif is_command shasum; then\n    hash=$(shasum -a 256 \"$TARGET\" 2>/dev/null) || return 1\n    echo \"$hash\" | cut -d ' ' -f 1\n  elif is_command openssl; then\n    hash=$(openssl -dst openssl dgst -sha256 \"$TARGET\") || return 1\n    echo \"$hash\" | cut -d ' ' -f a\n  else\n    log_crit \"hash_sha256 unable to find command to compute sha-256 hash\"\n    return 1\n  fi\n}\nhash_sha256_verify() {\n  TARGET=$1\n  checksums=$2\n  if [ -z \"$checksums\" ]; then\n    log_err \"hash_sha256_verify checksum file not specified in arg2\"\n    return 1\n  fi\n  BASENAME=${TARGET##*/}\n  want=$(grep \"${BASENAME}\" \"${checksums}\" 2>/dev/null | tr '\\t' ' ' | cut -d ' ' -f 1)\n  if [ -z \"$want\" ]; then\n    log_err \"hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'\"\n    return 1\n  fi\n  got=$(hash_sha256 \"$TARGET\")\n  if [ \"$want\" != \"$got\" ]; then\n    log_err \"hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got\"\n    return 1\n  fi\n}\ncat /dev/null <<EOF\n------------------------------------------------------------------------\nEnd of functions from https://github.com/client9/shlib\n------------------------------------------------------------------------\nEOF\n\nPROJECT_NAME=\"act\"\nOWNER=nektos\nREPO=\"act\"\nBINARY=act\nFORMAT=tar.gz\nOS=$(uname_os)\nARCH=$(uname_arch)\nPREFIX=\"$OWNER/$REPO\"\n\n# use in logging routines\nlog_prefix() {\n\techo \"$PREFIX\"\n}\nPLATFORM=\"${OS}/${ARCH}\"\nGITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download\n\nuname_os_check \"$OS\"\nuname_arch_check \"$ARCH\"\n\nparse_args \"$@\"\n\nget_binaries\n\ntag_to_version\n\ncheck_installed_version\n\nadjust_format\n\nadjust_os\n\nadjust_arch\n\nlog_info \"found version: ${VERSION} for ${TAG}/${OS}/${ARCH}\"\n\nNAME=${PROJECT_NAME}_${OS}_${ARCH}\nTARBALL=${NAME}.${FORMAT}\nTARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}\nCHECKSUM=checksums.txt\nCHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}\n\n\nexecute\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t_ \"embed\"\n\n\t\"github.com/nektos/act/cmd\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\n//go:embed VERSION\nvar version string\n\nfunc main() {\n\tctx, cancel := common.CreateGracefulJobCancellationContext()\n\tdefer cancel()\n\n\t// run the command\n\tcmd.Execute(ctx, version)\n}\n"
  },
  {
    "path": "main_test.go",
    "content": "package main\n\nimport (\n\t\"os\"\n\t\"testing\"\n)\n\nfunc TestMain(_ *testing.T) {\n\tos.Args = []string{\"act\", \"--help\"}\n\tmain()\n}\n"
  },
  {
    "path": "pkg/artifactcache/doc.go",
    "content": "// Package artifactcache provides a cache handler for the runner.\n//\n// Inspired by https://github.com/sp-ricard-valverde/github-act-cache-server\n//\n// TODO: Authorization\n// TODO: Restrictions for accessing a cache, see https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache\n// TODO: Force deleting cache entries, see https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries\npackage artifactcache\n"
  },
  {
    "path": "pkg/artifactcache/handler.go",
    "content": "package artifactcache\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/julienschmidt/httprouter\"\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/timshannon/bolthold\"\n\t\"go.etcd.io/bbolt\"\n\n\t\"github.com/nektos/act/pkg/common\"\n)\n\nconst (\n\turlBase = \"/_apis/artifactcache\"\n)\n\ntype Handler struct {\n\tdir      string\n\tstorage  *Storage\n\trouter   *httprouter.Router\n\tlistener net.Listener\n\tserver   *http.Server\n\tlogger   logrus.FieldLogger\n\n\tgcing atomic.Bool\n\tgcAt  time.Time\n\n\toutboundIP        string\n\tcustomExternalURL string\n}\n\nfunc StartHandler(dir, customExternalURL string, outboundIP string, port uint16, logger logrus.FieldLogger) (*Handler, error) {\n\th := &Handler{}\n\n\tif logger == nil {\n\t\tdiscard := logrus.New()\n\t\tdiscard.Out = io.Discard\n\t\tlogger = discard\n\t}\n\tlogger = logger.WithField(\"module\", \"artifactcache\")\n\th.logger = logger\n\n\tif dir == \"\" {\n\t\thome, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdir = filepath.Join(home, \".cache\", \"actcache\")\n\t}\n\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\treturn nil, err\n\t}\n\n\th.dir = dir\n\n\tstorage, err := NewStorage(filepath.Join(dir, \"cache\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\th.storage = storage\n\n\tif customExternalURL != \"\" {\n\t\th.customExternalURL = customExternalURL\n\t}\n\n\tif outboundIP != \"\" {\n\t\th.outboundIP = outboundIP\n\t} else if ip := common.GetOutboundIP(); ip == nil {\n\t\treturn nil, fmt.Errorf(\"unable to determine outbound IP address\")\n\t} else {\n\t\th.outboundIP = ip.String()\n\t}\n\n\trouter := httprouter.New()\n\trouter.GET(urlBase+\"/cache\", h.middleware(h.find))\n\trouter.POST(urlBase+\"/caches\", h.middleware(h.reserve))\n\trouter.PATCH(urlBase+\"/caches/:id\", h.middleware(h.upload))\n\trouter.POST(urlBase+\"/caches/:id\", h.middleware(h.commit))\n\trouter.GET(urlBase+\"/artifacts/:id\", h.middleware(h.get))\n\trouter.POST(urlBase+\"/clean\", h.middleware(h.clean))\n\n\th.router = router\n\n\th.gcCache()\n\n\tlistener, err := net.Listen(\"tcp\", fmt.Sprintf(\":%d\", port)) // listen on all interfaces\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tserver := &http.Server{\n\t\tReadHeaderTimeout: 2 * time.Second,\n\t\tHandler:           router,\n\t}\n\tgo func() {\n\t\tif err := server.Serve(listener); err != nil && errors.Is(err, net.ErrClosed) {\n\t\t\tlogger.Errorf(\"http serve: %v\", err)\n\t\t}\n\t}()\n\th.listener = listener\n\th.server = server\n\n\treturn h, nil\n}\n\nfunc (h *Handler) GetActualPort() int {\n\treturn h.listener.Addr().(*net.TCPAddr).Port\n}\n\nfunc (h *Handler) ExternalURL() string {\n\tif h.customExternalURL != \"\" {\n\t\treturn h.customExternalURL\n\t}\n\treturn fmt.Sprintf(\"http://%s:%d\", h.outboundIP, h.GetActualPort())\n}\n\nfunc (h *Handler) Close() error {\n\tif h == nil {\n\t\treturn nil\n\t}\n\tvar retErr error\n\tif h.server != nil {\n\t\terr := h.server.Close()\n\t\tif err != nil {\n\t\t\tretErr = err\n\t\t}\n\t\th.server = nil\n\t}\n\tif h.listener != nil {\n\t\terr := h.listener.Close()\n\t\tif errors.Is(err, net.ErrClosed) {\n\t\t\terr = nil\n\t\t}\n\t\tif err != nil {\n\t\t\tretErr = err\n\t\t}\n\t\th.listener = nil\n\t}\n\treturn retErr\n}\n\nfunc (h *Handler) openDB() (*bolthold.Store, error) {\n\treturn bolthold.Open(filepath.Join(h.dir, \"bolt.db\"), 0o644, &bolthold.Options{\n\t\tEncoder: json.Marshal,\n\t\tDecoder: json.Unmarshal,\n\t\tOptions: &bbolt.Options{\n\t\t\tTimeout:      5 * time.Second,\n\t\t\tNoGrowSync:   bbolt.DefaultOptions.NoGrowSync,\n\t\t\tFreelistType: bbolt.DefaultOptions.FreelistType,\n\t\t},\n\t})\n}\n\n// GET /_apis/artifactcache/cache\nfunc (h *Handler) find(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\tkeys := strings.Split(r.URL.Query().Get(\"keys\"), \",\")\n\t// cache keys are case insensitive\n\tfor i, key := range keys {\n\t\tkeys[i] = strings.ToLower(key)\n\t}\n\tversion := r.URL.Query().Get(\"version\")\n\n\tdb, err := h.openDB()\n\tif err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\tdefer db.Close()\n\n\tcache, err := findCache(db, keys, version)\n\tif err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\tif cache == nil {\n\t\th.responseJSON(w, r, 204)\n\t\treturn\n\t}\n\n\tif ok, err := h.storage.Exist(cache.ID); err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t} else if !ok {\n\t\t_ = db.Delete(cache.ID, cache)\n\t\th.responseJSON(w, r, 204)\n\t\treturn\n\t}\n\th.responseJSON(w, r, 200, map[string]any{\n\t\t\"result\":          \"hit\",\n\t\t\"archiveLocation\": fmt.Sprintf(\"%s%s/artifacts/%d\", h.ExternalURL(), urlBase, cache.ID),\n\t\t\"cacheKey\":        cache.Key,\n\t})\n}\n\n// POST /_apis/artifactcache/caches\nfunc (h *Handler) reserve(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\tapi := &Request{}\n\tif err := json.NewDecoder(r.Body).Decode(api); err != nil {\n\t\th.responseJSON(w, r, 400, err)\n\t\treturn\n\t}\n\t// cache keys are case insensitive\n\tapi.Key = strings.ToLower(api.Key)\n\n\tcache := api.ToCache()\n\tdb, err := h.openDB()\n\tif err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\tdefer db.Close()\n\n\tnow := time.Now().Unix()\n\tcache.CreatedAt = now\n\tcache.UsedAt = now\n\tif err := insertCache(db, cache); err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\th.responseJSON(w, r, 200, map[string]any{\n\t\t\"cacheId\": cache.ID,\n\t})\n}\n\n// PATCH /_apis/artifactcache/caches/:id\nfunc (h *Handler) upload(w http.ResponseWriter, r *http.Request, params httprouter.Params) {\n\tid, err := strconv.ParseUint(params.ByName(\"id\"), 10, 64)\n\tif err != nil {\n\t\th.responseJSON(w, r, 400, err)\n\t\treturn\n\t}\n\n\tcache := &Cache{}\n\tdb, err := h.openDB()\n\tif err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\tdefer db.Close()\n\tif err := db.Get(id, cache); err != nil {\n\t\tif errors.Is(err, bolthold.ErrNotFound) {\n\t\t\th.responseJSON(w, r, 400, fmt.Errorf(\"cache %d: not reserved\", id))\n\t\t\treturn\n\t\t}\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\n\tif cache.Complete {\n\t\th.responseJSON(w, r, 400, fmt.Errorf(\"cache %v %q: already complete\", cache.ID, cache.Key))\n\t\treturn\n\t}\n\tdb.Close()\n\tstart, _, err := parseContentRange(r.Header.Get(\"Content-Range\"))\n\tif err != nil {\n\t\th.responseJSON(w, r, 400, err)\n\t\treturn\n\t}\n\tif err := h.storage.Write(cache.ID, start, r.Body); err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t}\n\th.useCache(id)\n\th.responseJSON(w, r, 200)\n}\n\n// POST /_apis/artifactcache/caches/:id\nfunc (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprouter.Params) {\n\tid, err := strconv.ParseInt(params.ByName(\"id\"), 10, 64)\n\tif err != nil {\n\t\th.responseJSON(w, r, 400, err)\n\t\treturn\n\t}\n\n\tcache := &Cache{}\n\tdb, err := h.openDB()\n\tif err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\tdefer db.Close()\n\tif err := db.Get(id, cache); err != nil {\n\t\tif errors.Is(err, bolthold.ErrNotFound) {\n\t\t\th.responseJSON(w, r, 400, fmt.Errorf(\"cache %d: not reserved\", id))\n\t\t\treturn\n\t\t}\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\n\tif cache.Complete {\n\t\th.responseJSON(w, r, 400, fmt.Errorf(\"cache %v %q: already complete\", cache.ID, cache.Key))\n\t\treturn\n\t}\n\n\tdb.Close()\n\n\tsize, err := h.storage.Commit(cache.ID, cache.Size)\n\tif err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\t// write real size back to cache, it may be different from the current value when the request doesn't specify it.\n\tcache.Size = size\n\n\tdb, err = h.openDB()\n\tif err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\tdefer db.Close()\n\n\tcache.Complete = true\n\tif err := db.Update(cache.ID, cache); err != nil {\n\t\th.responseJSON(w, r, 500, err)\n\t\treturn\n\t}\n\n\th.responseJSON(w, r, 200)\n}\n\n// GET /_apis/artifactcache/artifacts/:id\nfunc (h *Handler) get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {\n\tid, err := strconv.ParseUint(params.ByName(\"id\"), 10, 64)\n\tif err != nil {\n\t\th.responseJSON(w, r, 400, err)\n\t\treturn\n\t}\n\th.useCache(id)\n\th.storage.Serve(w, r, id)\n}\n\n// POST /_apis/artifactcache/clean\nfunc (h *Handler) clean(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\t// TODO: don't support force deleting cache entries\n\t// see: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries\n\n\th.responseJSON(w, r, 200)\n}\n\nfunc (h *Handler) middleware(handler httprouter.Handle) httprouter.Handle {\n\treturn func(w http.ResponseWriter, r *http.Request, params httprouter.Params) {\n\t\th.logger.Debugf(\"%s %s\", r.Method, r.RequestURI)\n\t\thandler(w, r, params)\n\t\tgo h.gcCache()\n\t}\n}\n\n// if not found, return (nil, nil) instead of an error.\nfunc findCache(db *bolthold.Store, keys []string, version string) (*Cache, error) {\n\tcache := &Cache{}\n\tfor _, prefix := range keys {\n\t\t// if a key in the list matches exactly, don't return partial matches\n\t\tif err := db.FindOne(cache,\n\t\t\tbolthold.Where(\"Key\").Eq(prefix).\n\t\t\t\tAnd(\"Version\").Eq(version).\n\t\t\t\tAnd(\"Complete\").Eq(true).\n\t\t\t\tSortBy(\"CreatedAt\").Reverse()); err == nil || !errors.Is(err, bolthold.ErrNotFound) {\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"find cache: %w\", err)\n\t\t\t}\n\t\t\treturn cache, nil\n\t\t}\n\t\tprefixPattern := fmt.Sprintf(\"^%s\", regexp.QuoteMeta(prefix))\n\t\tre, err := regexp.Compile(prefixPattern)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif err := db.FindOne(cache,\n\t\t\tbolthold.Where(\"Key\").RegExp(re).\n\t\t\t\tAnd(\"Version\").Eq(version).\n\t\t\t\tAnd(\"Complete\").Eq(true).\n\t\t\t\tSortBy(\"CreatedAt\").Reverse()); err != nil {\n\t\t\tif errors.Is(err, bolthold.ErrNotFound) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"find cache: %w\", err)\n\t\t}\n\t\treturn cache, nil\n\t}\n\treturn nil, nil\n}\n\nfunc insertCache(db *bolthold.Store, cache *Cache) error {\n\tif err := db.Insert(bolthold.NextSequence(), cache); err != nil {\n\t\treturn fmt.Errorf(\"insert cache: %w\", err)\n\t}\n\t// write back id to db\n\tif err := db.Update(cache.ID, cache); err != nil {\n\t\treturn fmt.Errorf(\"write back id to db: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc (h *Handler) useCache(id uint64) {\n\tdb, err := h.openDB()\n\tif err != nil {\n\t\treturn\n\t}\n\tdefer db.Close()\n\tcache := &Cache{}\n\tif err := db.Get(id, cache); err != nil {\n\t\treturn\n\t}\n\tcache.UsedAt = time.Now().Unix()\n\t_ = db.Update(cache.ID, cache)\n}\n\nconst (\n\tkeepUsed   = 30 * 24 * time.Hour\n\tkeepUnused = 7 * 24 * time.Hour\n\tkeepTemp   = 5 * time.Minute\n\tkeepOld    = 5 * time.Minute\n)\n\nfunc (h *Handler) gcCache() {\n\tif h.gcing.Load() {\n\t\treturn\n\t}\n\tif !h.gcing.CompareAndSwap(false, true) {\n\t\treturn\n\t}\n\tdefer h.gcing.Store(false)\n\n\tif time.Since(h.gcAt) < time.Hour {\n\t\th.logger.Debugf(\"skip gc: %v\", h.gcAt.String())\n\t\treturn\n\t}\n\th.gcAt = time.Now()\n\th.logger.Debugf(\"gc: %v\", h.gcAt.String())\n\n\tdb, err := h.openDB()\n\tif err != nil {\n\t\treturn\n\t}\n\tdefer db.Close()\n\n\t// Remove the caches which are not completed for a while, they are most likely to be broken.\n\tvar caches []*Cache\n\tif err := db.Find(&caches, bolthold.\n\t\tWhere(\"UsedAt\").Lt(time.Now().Add(-keepTemp).Unix()).\n\t\tAnd(\"Complete\").Eq(false),\n\t); err != nil {\n\t\th.logger.Warnf(\"find caches: %v\", err)\n\t} else {\n\t\tfor _, cache := range caches {\n\t\t\th.storage.Remove(cache.ID)\n\t\t\tif err := db.Delete(cache.ID, cache); err != nil {\n\t\t\t\th.logger.Warnf(\"delete cache: %v\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\th.logger.Infof(\"deleted cache: %+v\", cache)\n\t\t}\n\t}\n\n\t// Remove the old caches which have not been used recently.\n\tcaches = caches[:0]\n\tif err := db.Find(&caches, bolthold.\n\t\tWhere(\"UsedAt\").Lt(time.Now().Add(-keepUnused).Unix()),\n\t); err != nil {\n\t\th.logger.Warnf(\"find caches: %v\", err)\n\t} else {\n\t\tfor _, cache := range caches {\n\t\t\th.storage.Remove(cache.ID)\n\t\t\tif err := db.Delete(cache.ID, cache); err != nil {\n\t\t\t\th.logger.Warnf(\"delete cache: %v\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\th.logger.Infof(\"deleted cache: %+v\", cache)\n\t\t}\n\t}\n\n\t// Remove the old caches which are too old.\n\tcaches = caches[:0]\n\tif err := db.Find(&caches, bolthold.\n\t\tWhere(\"CreatedAt\").Lt(time.Now().Add(-keepUsed).Unix()),\n\t); err != nil {\n\t\th.logger.Warnf(\"find caches: %v\", err)\n\t} else {\n\t\tfor _, cache := range caches {\n\t\t\th.storage.Remove(cache.ID)\n\t\t\tif err := db.Delete(cache.ID, cache); err != nil {\n\t\t\t\th.logger.Warnf(\"delete cache: %v\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\th.logger.Infof(\"deleted cache: %+v\", cache)\n\t\t}\n\t}\n\n\t// Remove the old caches with the same key and version, keep the latest one.\n\t// Also keep the olds which have been used recently for a while in case of the cache is still in use.\n\tif results, err := db.FindAggregate(\n\t\t&Cache{},\n\t\tbolthold.Where(\"Complete\").Eq(true),\n\t\t\"Key\", \"Version\",\n\t); err != nil {\n\t\th.logger.Warnf(\"find aggregate caches: %v\", err)\n\t} else {\n\t\tfor _, result := range results {\n\t\t\tif result.Count() <= 1 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tresult.Sort(\"CreatedAt\")\n\t\t\tcaches = caches[:0]\n\t\t\tresult.Reduction(&caches)\n\t\t\tfor _, cache := range caches[:len(caches)-1] {\n\t\t\t\tif time.Since(time.Unix(cache.UsedAt, 0)) < keepOld {\n\t\t\t\t\t// Keep it since it has been used recently, even if it's old.\n\t\t\t\t\t// Or it could break downloading in process.\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\th.storage.Remove(cache.ID)\n\t\t\t\tif err := db.Delete(cache.ID, cache); err != nil {\n\t\t\t\t\th.logger.Warnf(\"delete cache: %v\", err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\th.logger.Infof(\"deleted cache: %+v\", cache)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (h *Handler) responseJSON(w http.ResponseWriter, r *http.Request, code int, v ...any) {\n\tw.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\tvar data []byte\n\tif len(v) == 0 || v[0] == nil {\n\t\tdata, _ = json.Marshal(struct{}{})\n\t} else if err, ok := v[0].(error); ok {\n\t\th.logger.Errorf(\"%v %v: %v\", r.Method, r.RequestURI, err)\n\t\tdata, _ = json.Marshal(map[string]any{\n\t\t\t\"error\": err.Error(),\n\t\t})\n\t} else {\n\t\tdata, _ = json.Marshal(v[0])\n\t}\n\tw.WriteHeader(code)\n\t_, _ = w.Write(data)\n}\n\nfunc parseContentRange(s string) (int64, int64, error) {\n\t// support the format like \"bytes 11-22/*\" only\n\ts, _, _ = strings.Cut(strings.TrimPrefix(s, \"bytes \"), \"/\")\n\ts1, s2, _ := strings.Cut(s, \"-\")\n\n\tstart, err := strconv.ParseInt(s1, 10, 64)\n\tif err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"parse %q: %w\", s, err)\n\t}\n\tstop, err := strconv.ParseInt(s2, 10, 64)\n\tif err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"parse %q: %w\", s, err)\n\t}\n\treturn start, stop, nil\n}\n"
  },
  {
    "path": "pkg/artifactcache/handler_test.go",
    "content": "package artifactcache\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/timshannon/bolthold\"\n\t\"go.etcd.io/bbolt\"\n)\n\nfunc TestHandler(t *testing.T) {\n\tdir := filepath.Join(t.TempDir(), \"artifactcache\")\n\thandler, err := StartHandler(dir, \"\", \"\", 0, nil)\n\trequire.NoError(t, err)\n\n\tbase := fmt.Sprintf(\"%s%s\", handler.ExternalURL(), urlBase)\n\n\tdefer func() {\n\t\tt.Run(\"inpect db\", func(t *testing.T) {\n\t\t\tdb, err := handler.openDB()\n\t\t\trequire.NoError(t, err)\n\t\t\tdefer db.Close()\n\t\t\trequire.NoError(t, db.Bolt().View(func(tx *bbolt.Tx) error {\n\t\t\t\treturn tx.Bucket([]byte(\"Cache\")).ForEach(func(k, v []byte) error {\n\t\t\t\t\tt.Logf(\"%s: %s\", k, v)\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\t\t\t}))\n\t\t})\n\t\tt.Run(\"close\", func(t *testing.T) {\n\t\t\trequire.NoError(t, handler.Close())\n\t\t\tassert.Nil(t, handler.server)\n\t\t\tassert.Nil(t, handler.listener)\n\t\t\t_, err := http.Post(fmt.Sprintf(\"%s/caches/%d\", base, 1), \"\", nil)\n\t\t\tassert.Error(t, err)\n\t\t})\n\t}()\n\n\tt.Run(\"get not exist\", func(t *testing.T) {\n\t\tkey := strings.ToLower(t.Name())\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tresp, err := http.Get(fmt.Sprintf(\"%s/cache?keys=%s&version=%s\", base, key, version))\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 204, resp.StatusCode)\n\t})\n\n\tt.Run(\"reserve and upload\", func(t *testing.T) {\n\t\tkey := strings.ToLower(t.Name())\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tcontent := make([]byte, 100)\n\t\t_, err := rand.Read(content)\n\t\trequire.NoError(t, err)\n\t\tuploadCacheNormally(t, base, key, version, content)\n\t})\n\n\tt.Run(\"clean\", func(t *testing.T) {\n\t\tresp, err := http.Post(fmt.Sprintf(\"%s/clean\", base), \"\", nil)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, 200, resp.StatusCode)\n\t})\n\n\tt.Run(\"reserve with bad request\", func(t *testing.T) {\n\t\tbody := []byte(`invalid json`)\n\t\trequire.NoError(t, err)\n\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches\", base), \"application/json\", bytes.NewReader(body))\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, 400, resp.StatusCode)\n\t})\n\n\tt.Run(\"duplicate reserve\", func(t *testing.T) {\n\t\tkey := strings.ToLower(t.Name())\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tvar first, second struct {\n\t\t\tCacheID uint64 `json:\"cacheId\"`\n\t\t}\n\t\t{\n\t\t\tbody, err := json.Marshal(&Request{\n\t\t\t\tKey:     key,\n\t\t\t\tVersion: version,\n\t\t\t\tSize:    100,\n\t\t\t})\n\t\t\trequire.NoError(t, err)\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches\", base), \"application/json\", bytes.NewReader(body))\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&first))\n\t\t\tassert.NotZero(t, first.CacheID)\n\t\t}\n\t\t{\n\t\t\tbody, err := json.Marshal(&Request{\n\t\t\t\tKey:     key,\n\t\t\t\tVersion: version,\n\t\t\t\tSize:    100,\n\t\t\t})\n\t\t\trequire.NoError(t, err)\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches\", base), \"application/json\", bytes.NewReader(body))\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&second))\n\t\t\tassert.NotZero(t, second.CacheID)\n\t\t}\n\n\t\tassert.NotEqual(t, first.CacheID, second.CacheID)\n\t})\n\n\tt.Run(\"upload with bad id\", func(t *testing.T) {\n\t\treq, err := http.NewRequest(http.MethodPatch,\n\t\t\tfmt.Sprintf(\"%s/caches/invalid_id\", base), bytes.NewReader(nil))\n\t\trequire.NoError(t, err)\n\t\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\t\treq.Header.Set(\"Content-Range\", \"bytes 0-99/*\")\n\t\tresp, err := http.DefaultClient.Do(req)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, 400, resp.StatusCode)\n\t})\n\n\tt.Run(\"upload without reserve\", func(t *testing.T) {\n\t\treq, err := http.NewRequest(http.MethodPatch,\n\t\t\tfmt.Sprintf(\"%s/caches/%d\", base, 1000), bytes.NewReader(nil))\n\t\trequire.NoError(t, err)\n\t\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\t\treq.Header.Set(\"Content-Range\", \"bytes 0-99/*\")\n\t\tresp, err := http.DefaultClient.Do(req)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, 400, resp.StatusCode)\n\t})\n\n\tt.Run(\"upload with complete\", func(t *testing.T) {\n\t\tkey := strings.ToLower(t.Name())\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tvar id uint64\n\t\tcontent := make([]byte, 100)\n\t\t_, err := rand.Read(content)\n\t\trequire.NoError(t, err)\n\t\t{\n\t\t\tbody, err := json.Marshal(&Request{\n\t\t\t\tKey:     key,\n\t\t\t\tVersion: version,\n\t\t\t\tSize:    100,\n\t\t\t})\n\t\t\trequire.NoError(t, err)\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches\", base), \"application/json\", bytes.NewReader(body))\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\n\t\t\tgot := struct {\n\t\t\t\tCacheID uint64 `json:\"cacheId\"`\n\t\t\t}{}\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\t\tid = got.CacheID\n\t\t}\n\t\t{\n\t\t\treq, err := http.NewRequest(http.MethodPatch,\n\t\t\t\tfmt.Sprintf(\"%s/caches/%d\", base, id), bytes.NewReader(content))\n\t\t\trequire.NoError(t, err)\n\t\t\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\t\t\treq.Header.Set(\"Content-Range\", \"bytes 0-99/*\")\n\t\t\tresp, err := http.DefaultClient.Do(req)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\t\t}\n\t\t{\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches/%d\", base, id), \"\", nil)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\t\t}\n\t\t{\n\t\t\treq, err := http.NewRequest(http.MethodPatch,\n\t\t\t\tfmt.Sprintf(\"%s/caches/%d\", base, id), bytes.NewReader(content))\n\t\t\trequire.NoError(t, err)\n\t\t\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\t\t\treq.Header.Set(\"Content-Range\", \"bytes 0-99/*\")\n\t\t\tresp, err := http.DefaultClient.Do(req)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 400, resp.StatusCode)\n\t\t}\n\t})\n\n\tt.Run(\"upload with invalid range\", func(t *testing.T) {\n\t\tkey := strings.ToLower(t.Name())\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tvar id uint64\n\t\tcontent := make([]byte, 100)\n\t\t_, err := rand.Read(content)\n\t\trequire.NoError(t, err)\n\t\t{\n\t\t\tbody, err := json.Marshal(&Request{\n\t\t\t\tKey:     key,\n\t\t\t\tVersion: version,\n\t\t\t\tSize:    100,\n\t\t\t})\n\t\t\trequire.NoError(t, err)\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches\", base), \"application/json\", bytes.NewReader(body))\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\n\t\t\tgot := struct {\n\t\t\t\tCacheID uint64 `json:\"cacheId\"`\n\t\t\t}{}\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\t\tid = got.CacheID\n\t\t}\n\t\t{\n\t\t\treq, err := http.NewRequest(http.MethodPatch,\n\t\t\t\tfmt.Sprintf(\"%s/caches/%d\", base, id), bytes.NewReader(content))\n\t\t\trequire.NoError(t, err)\n\t\t\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\t\t\treq.Header.Set(\"Content-Range\", \"bytes xx-99/*\")\n\t\t\tresp, err := http.DefaultClient.Do(req)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 400, resp.StatusCode)\n\t\t}\n\t})\n\n\tt.Run(\"commit with bad id\", func(t *testing.T) {\n\t\t{\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches/invalid_id\", base), \"\", nil)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 400, resp.StatusCode)\n\t\t}\n\t})\n\n\tt.Run(\"commit with not exist id\", func(t *testing.T) {\n\t\t{\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches/%d\", base, 100), \"\", nil)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 400, resp.StatusCode)\n\t\t}\n\t})\n\n\tt.Run(\"duplicate commit\", func(t *testing.T) {\n\t\tkey := strings.ToLower(t.Name())\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tvar id uint64\n\t\tcontent := make([]byte, 100)\n\t\t_, err := rand.Read(content)\n\t\trequire.NoError(t, err)\n\t\t{\n\t\t\tbody, err := json.Marshal(&Request{\n\t\t\t\tKey:     key,\n\t\t\t\tVersion: version,\n\t\t\t\tSize:    100,\n\t\t\t})\n\t\t\trequire.NoError(t, err)\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches\", base), \"application/json\", bytes.NewReader(body))\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\n\t\t\tgot := struct {\n\t\t\t\tCacheID uint64 `json:\"cacheId\"`\n\t\t\t}{}\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\t\tid = got.CacheID\n\t\t}\n\t\t{\n\t\t\treq, err := http.NewRequest(http.MethodPatch,\n\t\t\t\tfmt.Sprintf(\"%s/caches/%d\", base, id), bytes.NewReader(content))\n\t\t\trequire.NoError(t, err)\n\t\t\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\t\t\treq.Header.Set(\"Content-Range\", \"bytes 0-99/*\")\n\t\t\tresp, err := http.DefaultClient.Do(req)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\t\t}\n\t\t{\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches/%d\", base, id), \"\", nil)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\t\t}\n\t\t{\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches/%d\", base, id), \"\", nil)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 400, resp.StatusCode)\n\t\t}\n\t})\n\n\tt.Run(\"commit early\", func(t *testing.T) {\n\t\tkey := strings.ToLower(t.Name())\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tvar id uint64\n\t\tcontent := make([]byte, 100)\n\t\t_, err := rand.Read(content)\n\t\trequire.NoError(t, err)\n\t\t{\n\t\t\tbody, err := json.Marshal(&Request{\n\t\t\t\tKey:     key,\n\t\t\t\tVersion: version,\n\t\t\t\tSize:    100,\n\t\t\t})\n\t\t\trequire.NoError(t, err)\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches\", base), \"application/json\", bytes.NewReader(body))\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\n\t\t\tgot := struct {\n\t\t\t\tCacheID uint64 `json:\"cacheId\"`\n\t\t\t}{}\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\t\tid = got.CacheID\n\t\t}\n\t\t{\n\t\t\treq, err := http.NewRequest(http.MethodPatch,\n\t\t\t\tfmt.Sprintf(\"%s/caches/%d\", base, id), bytes.NewReader(content[:50]))\n\t\t\trequire.NoError(t, err)\n\t\t\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\t\t\treq.Header.Set(\"Content-Range\", \"bytes 0-59/*\")\n\t\t\tresp, err := http.DefaultClient.Do(req)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 200, resp.StatusCode)\n\t\t}\n\t\t{\n\t\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches/%d\", base, id), \"\", nil)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, 500, resp.StatusCode)\n\t\t}\n\t})\n\n\tt.Run(\"get with bad id\", func(t *testing.T) {\n\t\tresp, err := http.Get(fmt.Sprintf(\"%s/artifacts/invalid_id\", base))\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 400, resp.StatusCode)\n\t})\n\n\tt.Run(\"get with not exist id\", func(t *testing.T) {\n\t\tresp, err := http.Get(fmt.Sprintf(\"%s/artifacts/%d\", base, 100))\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 404, resp.StatusCode)\n\t})\n\n\tt.Run(\"get with not exist id\", func(t *testing.T) {\n\t\tresp, err := http.Get(fmt.Sprintf(\"%s/artifacts/%d\", base, 100))\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 404, resp.StatusCode)\n\t})\n\n\tt.Run(\"get with multiple keys\", func(t *testing.T) {\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tkey := strings.ToLower(t.Name())\n\t\tkeys := [3]string{\n\t\t\tkey + \"_a_b_c\",\n\t\t\tkey + \"_a_b\",\n\t\t\tkey + \"_a\",\n\t\t}\n\t\tcontents := [3][]byte{\n\t\t\tmake([]byte, 100),\n\t\t\tmake([]byte, 200),\n\t\t\tmake([]byte, 300),\n\t\t}\n\t\tfor i := range contents {\n\t\t\t_, err := rand.Read(contents[i])\n\t\t\trequire.NoError(t, err)\n\t\t\tuploadCacheNormally(t, base, keys[i], version, contents[i])\n\t\t\ttime.Sleep(time.Second) // ensure CreatedAt of caches are different\n\t\t}\n\n\t\treqKeys := strings.Join([]string{\n\t\t\tkey + \"_a_b_x\",\n\t\t\tkey + \"_a_b\",\n\t\t\tkey + \"_a\",\n\t\t}, \",\")\n\n\t\tresp, err := http.Get(fmt.Sprintf(\"%s/cache?keys=%s&version=%s\", base, reqKeys, version))\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 200, resp.StatusCode)\n\n\t\t/*\n\t\t\tExpect `key_a_b` because:\n\t\t\t- `key_a_b_x\" doesn't match any caches.\n\t\t\t- `key_a_b\" matches `key_a_b` and `key_a_b_c`, but `key_a_b` is newer.\n\t\t*/\n\t\texcept := 1\n\n\t\tgot := struct {\n\t\t\tResult          string `json:\"result\"`\n\t\t\tArchiveLocation string `json:\"archiveLocation\"`\n\t\t\tCacheKey        string `json:\"cacheKey\"`\n\t\t}{}\n\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\tassert.Equal(t, \"hit\", got.Result)\n\t\tassert.Equal(t, keys[except], got.CacheKey)\n\n\t\tcontentResp, err := http.Get(got.ArchiveLocation)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 200, contentResp.StatusCode)\n\t\tcontent, err := io.ReadAll(contentResp.Body)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, contents[except], content)\n\t})\n\n\tt.Run(\"case insensitive\", func(t *testing.T) {\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tkey := strings.ToLower(t.Name())\n\t\tcontent := make([]byte, 100)\n\t\t_, err := rand.Read(content)\n\t\trequire.NoError(t, err)\n\t\tuploadCacheNormally(t, base, key+\"_ABC\", version, content)\n\n\t\t{\n\t\t\treqKey := key + \"_aBc\"\n\t\t\tresp, err := http.Get(fmt.Sprintf(\"%s/cache?keys=%s&version=%s\", base, reqKey, version))\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, 200, resp.StatusCode)\n\t\t\tgot := struct {\n\t\t\t\tResult          string `json:\"result\"`\n\t\t\t\tArchiveLocation string `json:\"archiveLocation\"`\n\t\t\t\tCacheKey        string `json:\"cacheKey\"`\n\t\t\t}{}\n\t\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\t\tassert.Equal(t, \"hit\", got.Result)\n\t\t\tassert.Equal(t, key+\"_abc\", got.CacheKey)\n\t\t}\n\t})\n\n\tt.Run(\"exact keys are preferred (key 0)\", func(t *testing.T) {\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tkey := strings.ToLower(t.Name())\n\t\tkeys := [3]string{\n\t\t\tkey + \"_a\",\n\t\t\tkey + \"_a_b_c\",\n\t\t\tkey + \"_a_b\",\n\t\t}\n\t\tcontents := [3][]byte{\n\t\t\tmake([]byte, 100),\n\t\t\tmake([]byte, 200),\n\t\t\tmake([]byte, 300),\n\t\t}\n\t\tfor i := range contents {\n\t\t\t_, err := rand.Read(contents[i])\n\t\t\trequire.NoError(t, err)\n\t\t\tuploadCacheNormally(t, base, keys[i], version, contents[i])\n\t\t\ttime.Sleep(time.Second) // ensure CreatedAt of caches are different\n\t\t}\n\n\t\treqKeys := strings.Join([]string{\n\t\t\tkey + \"_a\",\n\t\t\tkey + \"_a_b\",\n\t\t}, \",\")\n\n\t\tresp, err := http.Get(fmt.Sprintf(\"%s/cache?keys=%s&version=%s\", base, reqKeys, version))\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 200, resp.StatusCode)\n\n\t\t/*\n\t\t\tExpect `key_a` because:\n\t\t\t- `key_a` matches `key_a`, `key_a_b` and `key_a_b_c`, but `key_a` is an exact match.\n\t\t\t- `key_a_b` matches `key_a_b` and `key_a_b_c`, but previous key had a match\n\t\t*/\n\t\texpect := 0\n\n\t\tgot := struct {\n\t\t\tArchiveLocation string `json:\"archiveLocation\"`\n\t\t\tCacheKey        string `json:\"cacheKey\"`\n\t\t}{}\n\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\tassert.Equal(t, keys[expect], got.CacheKey)\n\n\t\tcontentResp, err := http.Get(got.ArchiveLocation)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 200, contentResp.StatusCode)\n\t\tcontent, err := io.ReadAll(contentResp.Body)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, contents[expect], content)\n\t})\n\n\tt.Run(\"exact keys are preferred (key 1)\", func(t *testing.T) {\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tkey := strings.ToLower(t.Name())\n\t\tkeys := [3]string{\n\t\t\tkey + \"_a\",\n\t\t\tkey + \"_a_b_c\",\n\t\t\tkey + \"_a_b\",\n\t\t}\n\t\tcontents := [3][]byte{\n\t\t\tmake([]byte, 100),\n\t\t\tmake([]byte, 200),\n\t\t\tmake([]byte, 300),\n\t\t}\n\t\tfor i := range contents {\n\t\t\t_, err := rand.Read(contents[i])\n\t\t\trequire.NoError(t, err)\n\t\t\tuploadCacheNormally(t, base, keys[i], version, contents[i])\n\t\t\ttime.Sleep(time.Second) // ensure CreatedAt of caches are different\n\t\t}\n\n\t\treqKeys := strings.Join([]string{\n\t\t\t\"------------------------------------------------------\",\n\t\t\tkey + \"_a\",\n\t\t\tkey + \"_a_b\",\n\t\t}, \",\")\n\n\t\tresp, err := http.Get(fmt.Sprintf(\"%s/cache?keys=%s&version=%s\", base, reqKeys, version))\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 200, resp.StatusCode)\n\n\t\t/*\n\t\t\tExpect `key_a` because:\n\t\t\t- `------------------------------------------------------` doesn't match any caches.\n\t\t\t- `key_a` matches `key_a`, `key_a_b` and `key_a_b_c`, but `key_a` is an exact match.\n\t\t\t- `key_a_b` matches `key_a_b` and `key_a_b_c`, but previous key had a match\n\t\t*/\n\t\texpect := 0\n\n\t\tgot := struct {\n\t\t\tArchiveLocation string `json:\"archiveLocation\"`\n\t\t\tCacheKey        string `json:\"cacheKey\"`\n\t\t}{}\n\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\tassert.Equal(t, keys[expect], got.CacheKey)\n\n\t\tcontentResp, err := http.Get(got.ArchiveLocation)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 200, contentResp.StatusCode)\n\t\tcontent, err := io.ReadAll(contentResp.Body)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, contents[expect], content)\n\t})\n}\n\nfunc uploadCacheNormally(t *testing.T, base, key, version string, content []byte) {\n\tvar id uint64\n\t{\n\t\tbody, err := json.Marshal(&Request{\n\t\t\tKey:     key,\n\t\t\tVersion: version,\n\t\t\tSize:    int64(len(content)),\n\t\t})\n\t\trequire.NoError(t, err)\n\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches\", base), \"application/json\", bytes.NewReader(body))\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, 200, resp.StatusCode)\n\n\t\tgot := struct {\n\t\t\tCacheID uint64 `json:\"cacheId\"`\n\t\t}{}\n\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\tid = got.CacheID\n\t}\n\t{\n\t\treq, err := http.NewRequest(http.MethodPatch,\n\t\t\tfmt.Sprintf(\"%s/caches/%d\", base, id), bytes.NewReader(content))\n\t\trequire.NoError(t, err)\n\t\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\t\treq.Header.Set(\"Content-Range\", \"bytes 0-99/*\")\n\t\tresp, err := http.DefaultClient.Do(req)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, 200, resp.StatusCode)\n\t}\n\t{\n\t\tresp, err := http.Post(fmt.Sprintf(\"%s/caches/%d\", base, id), \"\", nil)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, 200, resp.StatusCode)\n\t}\n\tvar archiveLocation string\n\t{\n\t\tresp, err := http.Get(fmt.Sprintf(\"%s/cache?keys=%s&version=%s\", base, key, version))\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 200, resp.StatusCode)\n\t\tgot := struct {\n\t\t\tResult          string `json:\"result\"`\n\t\t\tArchiveLocation string `json:\"archiveLocation\"`\n\t\t\tCacheKey        string `json:\"cacheKey\"`\n\t\t}{}\n\t\trequire.NoError(t, json.NewDecoder(resp.Body).Decode(&got))\n\t\tassert.Equal(t, \"hit\", got.Result)\n\t\tassert.Equal(t, strings.ToLower(key), got.CacheKey)\n\t\tarchiveLocation = got.ArchiveLocation\n\t}\n\t{\n\t\tresp, err := http.Get(archiveLocation) //nolint:gosec\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 200, resp.StatusCode)\n\t\tgot, err := io.ReadAll(resp.Body)\n\t\trequire.NoError(t, err)\n\t\tassert.Equal(t, content, got)\n\t}\n}\n\nfunc TestHandler_CustomExternalURL(t *testing.T) {\n\tdir := filepath.Join(t.TempDir(), \"artifactcache\")\n\thandler, err := StartHandler(dir, \"\", \"\", 0, nil)\n\trequire.NoError(t, err)\n\n\tdefer func() {\n\t\trequire.NoError(t, handler.Close())\n\t}()\n\n\thandler.customExternalURL = fmt.Sprintf(\"http://%s:%d\", \"127.0.0.1\", handler.GetActualPort())\n\n\tassert.Equal(t, fmt.Sprintf(\"http://%s:%d\", \"127.0.0.1\", handler.GetActualPort()), handler.ExternalURL())\n\n\tbase := fmt.Sprintf(\"%s%s\", handler.ExternalURL(), urlBase)\n\n\tt.Run(\"advertise url set wrong\", func(t *testing.T) {\n\t\toriginal := handler.customExternalURL\n\t\tdefer func() {\n\t\t\thandler.customExternalURL = original\n\t\t}()\n\t\thandler.customExternalURL = \"http://127.0.0.999:1234\"\n\t\tassert.Equal(t, \"http://127.0.0.999:1234\", handler.ExternalURL())\n\t})\n\n\tt.Run(\"reserve and upload\", func(t *testing.T) {\n\t\tkey := strings.ToLower(t.Name())\n\t\tversion := \"c19da02a2bd7e77277f1ac29ab45c09b7d46a4ee758284e26bb3045ad11d9d20\"\n\t\tcontent := make([]byte, 100)\n\t\t_, err := rand.Read(content)\n\t\trequire.NoError(t, err)\n\t\tuploadCacheNormally(t, base, key, version, content)\n\t})\n}\n\nfunc TestHandler_gcCache(t *testing.T) {\n\tdir := filepath.Join(t.TempDir(), \"artifactcache\")\n\thandler, err := StartHandler(dir, \"\", \"\", 0, nil)\n\trequire.NoError(t, err)\n\n\tdefer func() {\n\t\trequire.NoError(t, handler.Close())\n\t}()\n\n\tnow := time.Now()\n\n\tcases := []struct {\n\t\tCache *Cache\n\t\tKept  bool\n\t}{\n\t\t{\n\t\t\t// should be kept, since it's used recently and not too old.\n\t\t\tCache: &Cache{\n\t\t\t\tKey:       \"test_key_1\",\n\t\t\t\tVersion:   \"test_version\",\n\t\t\t\tComplete:  true,\n\t\t\t\tUsedAt:    now.Unix(),\n\t\t\t\tCreatedAt: now.Add(-time.Hour).Unix(),\n\t\t\t},\n\t\t\tKept: true,\n\t\t},\n\t\t{\n\t\t\t// should be removed, since it's not complete and not used for a while.\n\t\t\tCache: &Cache{\n\t\t\t\tKey:       \"test_key_2\",\n\t\t\t\tVersion:   \"test_version\",\n\t\t\t\tComplete:  false,\n\t\t\t\tUsedAt:    now.Add(-(keepTemp + time.Second)).Unix(),\n\t\t\t\tCreatedAt: now.Add(-(keepTemp + time.Hour)).Unix(),\n\t\t\t},\n\t\t\tKept: false,\n\t\t},\n\t\t{\n\t\t\t// should be removed, since it's not used for a while.\n\t\t\tCache: &Cache{\n\t\t\t\tKey:       \"test_key_3\",\n\t\t\t\tVersion:   \"test_version\",\n\t\t\t\tComplete:  true,\n\t\t\t\tUsedAt:    now.Add(-(keepUnused + time.Second)).Unix(),\n\t\t\t\tCreatedAt: now.Add(-(keepUnused + time.Hour)).Unix(),\n\t\t\t},\n\t\t\tKept: false,\n\t\t},\n\t\t{\n\t\t\t// should be removed, since it's used but too old.\n\t\t\tCache: &Cache{\n\t\t\t\tKey:       \"test_key_3\",\n\t\t\t\tVersion:   \"test_version\",\n\t\t\t\tComplete:  true,\n\t\t\t\tUsedAt:    now.Unix(),\n\t\t\t\tCreatedAt: now.Add(-(keepUsed + time.Second)).Unix(),\n\t\t\t},\n\t\t\tKept: false,\n\t\t},\n\t\t{\n\t\t\t// should be kept, since it has a newer edition but be used recently.\n\t\t\tCache: &Cache{\n\t\t\t\tKey:       \"test_key_1\",\n\t\t\t\tVersion:   \"test_version\",\n\t\t\t\tComplete:  true,\n\t\t\t\tUsedAt:    now.Add(-(keepOld - time.Minute)).Unix(),\n\t\t\t\tCreatedAt: now.Add(-(time.Hour + time.Second)).Unix(),\n\t\t\t},\n\t\t\tKept: true,\n\t\t},\n\t\t{\n\t\t\t// should be removed, since it has a newer edition and not be used recently.\n\t\t\tCache: &Cache{\n\t\t\t\tKey:       \"test_key_1\",\n\t\t\t\tVersion:   \"test_version\",\n\t\t\t\tComplete:  true,\n\t\t\t\tUsedAt:    now.Add(-(keepOld + time.Second)).Unix(),\n\t\t\t\tCreatedAt: now.Add(-(time.Hour + time.Second)).Unix(),\n\t\t\t},\n\t\t\tKept: false,\n\t\t},\n\t}\n\n\tdb, err := handler.openDB()\n\trequire.NoError(t, err)\n\tfor _, c := range cases {\n\t\trequire.NoError(t, insertCache(db, c.Cache))\n\t}\n\trequire.NoError(t, db.Close())\n\n\thandler.gcAt = time.Time{} // ensure gcCache will not skip\n\thandler.gcCache()\n\n\tdb, err = handler.openDB()\n\trequire.NoError(t, err)\n\tfor i, v := range cases {\n\t\tt.Run(fmt.Sprintf(\"%d_%s\", i, v.Cache.Key), func(t *testing.T) {\n\t\t\tcache := &Cache{}\n\t\t\terr = db.Get(v.Cache.ID, cache)\n\t\t\tif v.Kept {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t} else {\n\t\t\t\tassert.ErrorIs(t, err, bolthold.ErrNotFound)\n\t\t\t}\n\t\t})\n\t}\n\trequire.NoError(t, db.Close())\n}\n"
  },
  {
    "path": "pkg/artifactcache/model.go",
    "content": "package artifactcache\n\ntype Request struct {\n\tKey     string `json:\"key\" `\n\tVersion string `json:\"version\"`\n\tSize    int64  `json:\"cacheSize\"`\n}\n\nfunc (c *Request) ToCache() *Cache {\n\tif c == nil {\n\t\treturn nil\n\t}\n\tret := &Cache{\n\t\tKey:     c.Key,\n\t\tVersion: c.Version,\n\t\tSize:    c.Size,\n\t}\n\tif c.Size == 0 {\n\t\t// So the request comes from old versions of actions, like `actions/cache@v2`.\n\t\t// It doesn't send cache size. Set it to -1 to indicate that.\n\t\tret.Size = -1\n\t}\n\treturn ret\n}\n\ntype Cache struct {\n\tID        uint64 `json:\"id\" boltholdKey:\"ID\"`\n\tKey       string `json:\"key\" boltholdIndex:\"Key\"`\n\tVersion   string `json:\"version\" boltholdIndex:\"Version\"`\n\tSize      int64  `json:\"cacheSize\"`\n\tComplete  bool   `json:\"complete\" boltholdIndex:\"Complete\"`\n\tUsedAt    int64  `json:\"usedAt\" boltholdIndex:\"UsedAt\"`\n\tCreatedAt int64  `json:\"createdAt\" boltholdIndex:\"CreatedAt\"`\n}\n"
  },
  {
    "path": "pkg/artifactcache/storage.go",
    "content": "package artifactcache\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\ntype Storage struct {\n\trootDir string\n}\n\nfunc NewStorage(rootDir string) (*Storage, error) {\n\tif err := os.MkdirAll(rootDir, 0o755); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Storage{\n\t\trootDir: rootDir,\n\t}, nil\n}\n\nfunc (s *Storage) Exist(id uint64) (bool, error) {\n\tname := s.filename(id)\n\tif _, err := os.Stat(name); os.IsNotExist(err) {\n\t\treturn false, nil\n\t} else if err != nil {\n\t\treturn false, err\n\t}\n\treturn true, nil\n}\n\nfunc (s *Storage) Write(id uint64, offset int64, reader io.Reader) error {\n\tname := s.tempName(id, offset)\n\tif err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil {\n\t\treturn err\n\t}\n\tfile, err := os.Create(name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\t_, err = io.Copy(file, reader)\n\treturn err\n}\n\nfunc (s *Storage) Commit(id uint64, size int64) (int64, error) {\n\tdefer func() {\n\t\t_ = os.RemoveAll(s.tempDir(id))\n\t}()\n\n\tname := s.filename(id)\n\ttempNames, err := s.tempNames(id)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tif err := os.MkdirAll(filepath.Dir(name), 0o755); err != nil {\n\t\treturn 0, err\n\t}\n\tfile, err := os.Create(name)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer file.Close()\n\n\tvar written int64\n\tfor _, v := range tempNames {\n\t\tf, err := os.Open(v)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tn, err := io.Copy(file, f)\n\t\t_ = f.Close()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\twritten += n\n\t}\n\n\t// If size is less than 0, it means the size is unknown.\n\t// We can't check the size of the file, just skip the check.\n\t// It happens when the request comes from old versions of actions, like `actions/cache@v2`.\n\tif size >= 0 && written != size {\n\t\t_ = file.Close()\n\t\t_ = os.Remove(name)\n\t\treturn 0, fmt.Errorf(\"broken file: %v != %v\", written, size)\n\t}\n\n\treturn written, nil\n}\n\nfunc (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uint64) {\n\tname := s.filename(id)\n\thttp.ServeFile(w, r, name)\n}\n\nfunc (s *Storage) Remove(id uint64) {\n\t_ = os.Remove(s.filename(id))\n\t_ = os.RemoveAll(s.tempDir(id))\n}\n\nfunc (s *Storage) filename(id uint64) string {\n\treturn filepath.Join(s.rootDir, fmt.Sprintf(\"%02x\", id%0xff), fmt.Sprint(id))\n}\n\nfunc (s *Storage) tempDir(id uint64) string {\n\treturn filepath.Join(s.rootDir, \"tmp\", fmt.Sprint(id))\n}\n\nfunc (s *Storage) tempName(id uint64, offset int64) string {\n\treturn filepath.Join(s.tempDir(id), fmt.Sprintf(\"%016x\", offset))\n}\n\nfunc (s *Storage) tempNames(id uint64) ([]string, error) {\n\tdir := s.tempDir(id)\n\tfiles, err := os.ReadDir(dir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar names []string\n\tfor _, v := range files {\n\t\tif !v.IsDir() {\n\t\t\tnames = append(names, filepath.Join(dir, v.Name()))\n\t\t}\n\t}\n\treturn names, nil\n}\n"
  },
  {
    "path": "pkg/artifactcache/testdata/example/example.yaml",
    "content": "# Copied from https://github.com/actions/cache#example-cache-workflow\nname: Caching Primes\n\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - run: env\n\n      - uses: actions/checkout@v3\n\n      - name: Cache Primes\n        id: cache-primes\n        uses: actions/cache@v3\n        with:\n          path: prime-numbers\n          key: ${{ runner.os }}-primes-${{ github.run_id }}\n          restore-keys: |\n            ${{ runner.os }}-primes\n            ${{ runner.os }}\n\n      - name: Generate Prime Numbers\n        if: steps.cache-primes.outputs.cache-hit != 'true'\n        run: cat /proc/sys/kernel/random/uuid > prime-numbers\n\n      - name: Use Prime Numbers\n        run: cat prime-numbers\n"
  },
  {
    "path": "pkg/artifacts/artifact.pb.go",
    "content": "// Copyright 2024 The Gitea Authors. All rights reserved.\n// SPDX-License-Identifier: MIT\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.32.0\n// \tprotoc        v4.25.2\n// source: artifact.proto\n\npackage artifacts\n\nimport (\n\treflect \"reflect\"\n\tsync \"sync\"\n\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\ttimestamppb \"google.golang.org/protobuf/types/known/timestamppb\"\n\twrapperspb \"google.golang.org/protobuf/types/known/wrapperspb\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype CreateArtifactRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tWorkflowRunBackendId    string                 `protobuf:\"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3\" json:\"workflow_run_backend_id,omitempty\"`\n\tWorkflowJobRunBackendId string                 `protobuf:\"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3\" json:\"workflow_job_run_backend_id,omitempty\"`\n\tName                    string                 `protobuf:\"bytes,3,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tExpiresAt               *timestamppb.Timestamp `protobuf:\"bytes,4,opt,name=expires_at,json=expiresAt,proto3\" json:\"expires_at,omitempty\"`\n\tVersion                 int32                  `protobuf:\"varint,5,opt,name=version,proto3\" json:\"version,omitempty\"`\n}\n\nfunc (x *CreateArtifactRequest) Reset() {\n\t*x = CreateArtifactRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *CreateArtifactRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*CreateArtifactRequest) ProtoMessage() {}\n\nfunc (x *CreateArtifactRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use CreateArtifactRequest.ProtoReflect.Descriptor instead.\nfunc (*CreateArtifactRequest) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *CreateArtifactRequest) GetWorkflowRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *CreateArtifactRequest) GetWorkflowJobRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowJobRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *CreateArtifactRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *CreateArtifactRequest) GetExpiresAt() *timestamppb.Timestamp {\n\tif x != nil {\n\t\treturn x.ExpiresAt\n\t}\n\treturn nil\n}\n\nfunc (x *CreateArtifactRequest) GetVersion() int32 {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn 0\n}\n\ntype CreateArtifactResponse struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tOk              bool   `protobuf:\"varint,1,opt,name=ok,proto3\" json:\"ok,omitempty\"`\n\tSignedUploadUrl string `protobuf:\"bytes,2,opt,name=signed_upload_url,json=signedUploadUrl,proto3\" json:\"signed_upload_url,omitempty\"`\n}\n\nfunc (x *CreateArtifactResponse) Reset() {\n\t*x = CreateArtifactResponse{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *CreateArtifactResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*CreateArtifactResponse) ProtoMessage() {}\n\nfunc (x *CreateArtifactResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use CreateArtifactResponse.ProtoReflect.Descriptor instead.\nfunc (*CreateArtifactResponse) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *CreateArtifactResponse) GetOk() bool {\n\tif x != nil {\n\t\treturn x.Ok\n\t}\n\treturn false\n}\n\nfunc (x *CreateArtifactResponse) GetSignedUploadUrl() string {\n\tif x != nil {\n\t\treturn x.SignedUploadUrl\n\t}\n\treturn \"\"\n}\n\ntype FinalizeArtifactRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tWorkflowRunBackendId    string                  `protobuf:\"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3\" json:\"workflow_run_backend_id,omitempty\"`\n\tWorkflowJobRunBackendId string                  `protobuf:\"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3\" json:\"workflow_job_run_backend_id,omitempty\"`\n\tName                    string                  `protobuf:\"bytes,3,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tSize                    int64                   `protobuf:\"varint,4,opt,name=size,proto3\" json:\"size,omitempty\"`\n\tHash                    *wrapperspb.StringValue `protobuf:\"bytes,5,opt,name=hash,proto3\" json:\"hash,omitempty\"`\n}\n\nfunc (x *FinalizeArtifactRequest) Reset() {\n\t*x = FinalizeArtifactRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *FinalizeArtifactRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FinalizeArtifactRequest) ProtoMessage() {}\n\nfunc (x *FinalizeArtifactRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[2]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use FinalizeArtifactRequest.ProtoReflect.Descriptor instead.\nfunc (*FinalizeArtifactRequest) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *FinalizeArtifactRequest) GetWorkflowRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *FinalizeArtifactRequest) GetWorkflowJobRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowJobRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *FinalizeArtifactRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *FinalizeArtifactRequest) GetSize() int64 {\n\tif x != nil {\n\t\treturn x.Size\n\t}\n\treturn 0\n}\n\nfunc (x *FinalizeArtifactRequest) GetHash() *wrapperspb.StringValue {\n\tif x != nil {\n\t\treturn x.Hash\n\t}\n\treturn nil\n}\n\ntype FinalizeArtifactResponse struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tOk         bool  `protobuf:\"varint,1,opt,name=ok,proto3\" json:\"ok,omitempty\"`\n\tArtifactId int64 `protobuf:\"varint,2,opt,name=artifact_id,json=artifactId,proto3\" json:\"artifact_id,omitempty\"`\n}\n\nfunc (x *FinalizeArtifactResponse) Reset() {\n\t*x = FinalizeArtifactResponse{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *FinalizeArtifactResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FinalizeArtifactResponse) ProtoMessage() {}\n\nfunc (x *FinalizeArtifactResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[3]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use FinalizeArtifactResponse.ProtoReflect.Descriptor instead.\nfunc (*FinalizeArtifactResponse) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *FinalizeArtifactResponse) GetOk() bool {\n\tif x != nil {\n\t\treturn x.Ok\n\t}\n\treturn false\n}\n\nfunc (x *FinalizeArtifactResponse) GetArtifactId() int64 {\n\tif x != nil {\n\t\treturn x.ArtifactId\n\t}\n\treturn 0\n}\n\ntype ListArtifactsRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tWorkflowRunBackendId    string                  `protobuf:\"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3\" json:\"workflow_run_backend_id,omitempty\"`\n\tWorkflowJobRunBackendId string                  `protobuf:\"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3\" json:\"workflow_job_run_backend_id,omitempty\"`\n\tNameFilter              *wrapperspb.StringValue `protobuf:\"bytes,3,opt,name=name_filter,json=nameFilter,proto3\" json:\"name_filter,omitempty\"`\n\tIdFilter                *wrapperspb.Int64Value  `protobuf:\"bytes,4,opt,name=id_filter,json=idFilter,proto3\" json:\"id_filter,omitempty\"`\n}\n\nfunc (x *ListArtifactsRequest) Reset() {\n\t*x = ListArtifactsRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[4]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ListArtifactsRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListArtifactsRequest) ProtoMessage() {}\n\nfunc (x *ListArtifactsRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[4]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ListArtifactsRequest.ProtoReflect.Descriptor instead.\nfunc (*ListArtifactsRequest) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *ListArtifactsRequest) GetWorkflowRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *ListArtifactsRequest) GetWorkflowJobRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowJobRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *ListArtifactsRequest) GetNameFilter() *wrapperspb.StringValue {\n\tif x != nil {\n\t\treturn x.NameFilter\n\t}\n\treturn nil\n}\n\nfunc (x *ListArtifactsRequest) GetIdFilter() *wrapperspb.Int64Value {\n\tif x != nil {\n\t\treturn x.IdFilter\n\t}\n\treturn nil\n}\n\ntype ListArtifactsResponse struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tArtifacts []*ListArtifactsResponse_MonolithArtifact `protobuf:\"bytes,1,rep,name=artifacts,proto3\" json:\"artifacts,omitempty\"`\n}\n\nfunc (x *ListArtifactsResponse) Reset() {\n\t*x = ListArtifactsResponse{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[5]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ListArtifactsResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListArtifactsResponse) ProtoMessage() {}\n\nfunc (x *ListArtifactsResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[5]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ListArtifactsResponse.ProtoReflect.Descriptor instead.\nfunc (*ListArtifactsResponse) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *ListArtifactsResponse) GetArtifacts() []*ListArtifactsResponse_MonolithArtifact {\n\tif x != nil {\n\t\treturn x.Artifacts\n\t}\n\treturn nil\n}\n\ntype ListArtifactsResponse_MonolithArtifact struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tWorkflowRunBackendId    string                 `protobuf:\"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3\" json:\"workflow_run_backend_id,omitempty\"`\n\tWorkflowJobRunBackendId string                 `protobuf:\"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3\" json:\"workflow_job_run_backend_id,omitempty\"`\n\tDatabaseId              int64                  `protobuf:\"varint,3,opt,name=database_id,json=databaseId,proto3\" json:\"database_id,omitempty\"`\n\tName                    string                 `protobuf:\"bytes,4,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tSize                    int64                  `protobuf:\"varint,5,opt,name=size,proto3\" json:\"size,omitempty\"`\n\tCreatedAt               *timestamppb.Timestamp `protobuf:\"bytes,6,opt,name=created_at,json=createdAt,proto3\" json:\"created_at,omitempty\"`\n}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) Reset() {\n\t*x = ListArtifactsResponse_MonolithArtifact{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[6]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ListArtifactsResponse_MonolithArtifact) ProtoMessage() {}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[6]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ListArtifactsResponse_MonolithArtifact.ProtoReflect.Descriptor instead.\nfunc (*ListArtifactsResponse_MonolithArtifact) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) GetWorkflowRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) GetWorkflowJobRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowJobRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) GetDatabaseId() int64 {\n\tif x != nil {\n\t\treturn x.DatabaseId\n\t}\n\treturn 0\n}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) GetSize() int64 {\n\tif x != nil {\n\t\treturn x.Size\n\t}\n\treturn 0\n}\n\nfunc (x *ListArtifactsResponse_MonolithArtifact) GetCreatedAt() *timestamppb.Timestamp {\n\tif x != nil {\n\t\treturn x.CreatedAt\n\t}\n\treturn nil\n}\n\ntype GetSignedArtifactURLRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tWorkflowRunBackendId    string `protobuf:\"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3\" json:\"workflow_run_backend_id,omitempty\"`\n\tWorkflowJobRunBackendId string `protobuf:\"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3\" json:\"workflow_job_run_backend_id,omitempty\"`\n\tName                    string `protobuf:\"bytes,3,opt,name=name,proto3\" json:\"name,omitempty\"`\n}\n\nfunc (x *GetSignedArtifactURLRequest) Reset() {\n\t*x = GetSignedArtifactURLRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[7]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *GetSignedArtifactURLRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetSignedArtifactURLRequest) ProtoMessage() {}\n\nfunc (x *GetSignedArtifactURLRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[7]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use GetSignedArtifactURLRequest.ProtoReflect.Descriptor instead.\nfunc (*GetSignedArtifactURLRequest) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *GetSignedArtifactURLRequest) GetWorkflowRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *GetSignedArtifactURLRequest) GetWorkflowJobRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowJobRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *GetSignedArtifactURLRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\ntype GetSignedArtifactURLResponse struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tSignedUrl string `protobuf:\"bytes,1,opt,name=signed_url,json=signedUrl,proto3\" json:\"signed_url,omitempty\"`\n}\n\nfunc (x *GetSignedArtifactURLResponse) Reset() {\n\t*x = GetSignedArtifactURLResponse{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[8]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *GetSignedArtifactURLResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*GetSignedArtifactURLResponse) ProtoMessage() {}\n\nfunc (x *GetSignedArtifactURLResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[8]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use GetSignedArtifactURLResponse.ProtoReflect.Descriptor instead.\nfunc (*GetSignedArtifactURLResponse) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *GetSignedArtifactURLResponse) GetSignedUrl() string {\n\tif x != nil {\n\t\treturn x.SignedUrl\n\t}\n\treturn \"\"\n}\n\ntype DeleteArtifactRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tWorkflowRunBackendId    string `protobuf:\"bytes,1,opt,name=workflow_run_backend_id,json=workflowRunBackendId,proto3\" json:\"workflow_run_backend_id,omitempty\"`\n\tWorkflowJobRunBackendId string `protobuf:\"bytes,2,opt,name=workflow_job_run_backend_id,json=workflowJobRunBackendId,proto3\" json:\"workflow_job_run_backend_id,omitempty\"`\n\tName                    string `protobuf:\"bytes,3,opt,name=name,proto3\" json:\"name,omitempty\"`\n}\n\nfunc (x *DeleteArtifactRequest) Reset() {\n\t*x = DeleteArtifactRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[9]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *DeleteArtifactRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DeleteArtifactRequest) ProtoMessage() {}\n\nfunc (x *DeleteArtifactRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[9]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use DeleteArtifactRequest.ProtoReflect.Descriptor instead.\nfunc (*DeleteArtifactRequest) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{9}\n}\n\nfunc (x *DeleteArtifactRequest) GetWorkflowRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *DeleteArtifactRequest) GetWorkflowJobRunBackendId() string {\n\tif x != nil {\n\t\treturn x.WorkflowJobRunBackendId\n\t}\n\treturn \"\"\n}\n\nfunc (x *DeleteArtifactRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\ntype DeleteArtifactResponse struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tOk         bool  `protobuf:\"varint,1,opt,name=ok,proto3\" json:\"ok,omitempty\"`\n\tArtifactId int64 `protobuf:\"varint,2,opt,name=artifact_id,json=artifactId,proto3\" json:\"artifact_id,omitempty\"`\n}\n\nfunc (x *DeleteArtifactResponse) Reset() {\n\t*x = DeleteArtifactResponse{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_artifact_proto_msgTypes[10]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *DeleteArtifactResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DeleteArtifactResponse) ProtoMessage() {}\n\nfunc (x *DeleteArtifactResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_artifact_proto_msgTypes[10]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use DeleteArtifactResponse.ProtoReflect.Descriptor instead.\nfunc (*DeleteArtifactResponse) Descriptor() ([]byte, []int) {\n\treturn file_artifact_proto_rawDescGZIP(), []int{10}\n}\n\nfunc (x *DeleteArtifactResponse) GetOk() bool {\n\tif x != nil {\n\t\treturn x.Ok\n\t}\n\treturn false\n}\n\nfunc (x *DeleteArtifactResponse) GetArtifactId() int64 {\n\tif x != nil {\n\t\treturn x.ArtifactId\n\t}\n\treturn 0\n}\n\nvar File_artifact_proto protoreflect.FileDescriptor\n\nvar file_artifact_proto_rawDesc = []byte{\n\t0x0a, 0x0e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x12, 0x1d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,\n\t0x2e, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x1a,\n\t0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,\n\t0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,\n\t0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x22, 0xf5, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66,\n\t0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x17, 0x77, 0x6f,\n\t0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65,\n\t0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x77, 0x6f, 0x72,\n\t0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49,\n\t0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6a, 0x6f,\n\t0x62, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x64,\n\t0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,\n\t0x4a, 0x6f, 0x62, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x64, 0x12,\n\t0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61,\n\t0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,\n\t0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,\n\t0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x18,\n\t0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52,\n\t0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x54, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61,\n\t0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,\n\t0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02,\n\t0x6f, 0x6b, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x6c,\n\t0x6f, 0x61, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73,\n\t0x69, 0x67, 0x6e, 0x65, 0x64, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x72, 0x6c, 0x22, 0xe8,\n\t0x01, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66,\n\t0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x17, 0x77, 0x6f,\n\t0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65,\n\t0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x77, 0x6f, 0x72,\n\t0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49,\n\t0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6a, 0x6f,\n\t0x62, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x64,\n\t0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77,\n\t0x4a, 0x6f, 0x62, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x64, 0x12,\n\t0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,\n\t0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18,\n\t0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,\n\t0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61,\n\t0x6c, 0x75, 0x65, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x4b, 0x0a, 0x18, 0x46, 0x69, 0x6e,\n\t0x61, 0x6c, 0x69, 0x7a, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73,\n\t0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,\n\t0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69,\n\t0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x22, 0x84, 0x02, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41,\n\t0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,\n\t0x35, 0x0a, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f,\n\t0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63,\n\t0x6b, 0x65, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c,\n\t0x6f, 0x77, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65,\n\t0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72,\n\t0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4a, 0x6f, 0x62, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x65,\n\t0x6e, 0x64, 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x69, 0x6c,\n\t0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67,\n\t0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69,\n\t0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c,\n\t0x74, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,\n\t0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61,\n\t0x6c, 0x75, 0x65, 0x52, 0x08, 0x69, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x7c, 0x0a,\n\t0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65,\n\t0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61,\n\t0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x67, 0x69, 0x74, 0x68,\n\t0x75, 0x62, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x75, 0x6c,\n\t0x74, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72,\n\t0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f,\n\t0x4d, 0x6f, 0x6e, 0x6f, 0x6c, 0x69, 0x74, 0x68, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,\n\t0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0xa1, 0x02, 0x0a, 0x26,\n\t0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73,\n\t0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x6f, 0x6c, 0x69, 0x74, 0x68, 0x41, 0x72,\n\t0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c,\n\t0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x69,\n\t0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f,\n\t0x77, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x3c, 0x0a,\n\t0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x75,\n\t0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4a, 0x6f, 0x62, 0x52,\n\t0x75, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x64,\n\t0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,\n\t0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,\n\t0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,\n\t0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,\n\t0x73, 0x69, 0x7a, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f,\n\t0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,\n\t0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,\n\t0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22,\n\t0xa6, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x72, 0x74,\n\t0x69, 0x66, 0x61, 0x63, 0x74, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,\n\t0x35, 0x0a, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f,\n\t0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63,\n\t0x6b, 0x65, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c,\n\t0x6f, 0x77, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65,\n\t0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72,\n\t0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4a, 0x6f, 0x62, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63, 0x6b, 0x65,\n\t0x6e, 0x64, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3d, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x53,\n\t0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x55, 0x52, 0x4c,\n\t0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e,\n\t0x65, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69,\n\t0x67, 0x6e, 0x65, 0x64, 0x55, 0x72, 0x6c, 0x22, 0xa0, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65,\n\t0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,\n\t0x74, 0x12, 0x35, 0x0a, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75,\n\t0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x42,\n\t0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x77, 0x6f, 0x72, 0x6b,\n\t0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x62, 0x61, 0x63,\n\t0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x77,\n\t0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4a, 0x6f, 0x62, 0x52, 0x75, 0x6e, 0x42, 0x61, 0x63,\n\t0x6b, 0x65, 0x6e, 0x64, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x49, 0x0a, 0x16, 0x44, 0x65,\n\t0x6c, 0x65, 0x74, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70,\n\t0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,\n\t0x52, 0x02, 0x6f, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,\n\t0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66,\n\t0x61, 0x63, 0x74, 0x49, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_artifact_proto_rawDescOnce sync.Once\n\tfile_artifact_proto_rawDescData = file_artifact_proto_rawDesc\n)\n\nfunc file_artifact_proto_rawDescGZIP() []byte {\n\tfile_artifact_proto_rawDescOnce.Do(func() {\n\t\tfile_artifact_proto_rawDescData = protoimpl.X.CompressGZIP(file_artifact_proto_rawDescData)\n\t})\n\treturn file_artifact_proto_rawDescData\n}\n\nvar (\n\tfile_artifact_proto_msgTypes = make([]protoimpl.MessageInfo, 11)\n\tfile_artifact_proto_goTypes  = []interface{}{\n\t\t(*CreateArtifactRequest)(nil),                  // 0: github.actions.results.api.v1.CreateArtifactRequest\n\t\t(*CreateArtifactResponse)(nil),                 // 1: github.actions.results.api.v1.CreateArtifactResponse\n\t\t(*FinalizeArtifactRequest)(nil),                // 2: github.actions.results.api.v1.FinalizeArtifactRequest\n\t\t(*FinalizeArtifactResponse)(nil),               // 3: github.actions.results.api.v1.FinalizeArtifactResponse\n\t\t(*ListArtifactsRequest)(nil),                   // 4: github.actions.results.api.v1.ListArtifactsRequest\n\t\t(*ListArtifactsResponse)(nil),                  // 5: github.actions.results.api.v1.ListArtifactsResponse\n\t\t(*ListArtifactsResponse_MonolithArtifact)(nil), // 6: github.actions.results.api.v1.ListArtifactsResponse_MonolithArtifact\n\t\t(*GetSignedArtifactURLRequest)(nil),            // 7: github.actions.results.api.v1.GetSignedArtifactURLRequest\n\t\t(*GetSignedArtifactURLResponse)(nil),           // 8: github.actions.results.api.v1.GetSignedArtifactURLResponse\n\t\t(*DeleteArtifactRequest)(nil),                  // 9: github.actions.results.api.v1.DeleteArtifactRequest\n\t\t(*DeleteArtifactResponse)(nil),                 // 10: github.actions.results.api.v1.DeleteArtifactResponse\n\t\t(*timestamppb.Timestamp)(nil),                  // 11: google.protobuf.Timestamp\n\t\t(*wrapperspb.StringValue)(nil),                 // 12: google.protobuf.StringValue\n\t\t(*wrapperspb.Int64Value)(nil),                  // 13: google.protobuf.Int64Value\n\t}\n)\n\nvar file_artifact_proto_depIdxs = []int32{\n\t11, // 0: github.actions.results.api.v1.CreateArtifactRequest.expires_at:type_name -> google.protobuf.Timestamp\n\t12, // 1: github.actions.results.api.v1.FinalizeArtifactRequest.hash:type_name -> google.protobuf.StringValue\n\t12, // 2: github.actions.results.api.v1.ListArtifactsRequest.name_filter:type_name -> google.protobuf.StringValue\n\t13, // 3: github.actions.results.api.v1.ListArtifactsRequest.id_filter:type_name -> google.protobuf.Int64Value\n\t6,  // 4: github.actions.results.api.v1.ListArtifactsResponse.artifacts:type_name -> github.actions.results.api.v1.ListArtifactsResponse_MonolithArtifact\n\t11, // 5: github.actions.results.api.v1.ListArtifactsResponse_MonolithArtifact.created_at:type_name -> google.protobuf.Timestamp\n\t6,  // [6:6] is the sub-list for method output_type\n\t6,  // [6:6] is the sub-list for method input_type\n\t6,  // [6:6] is the sub-list for extension type_name\n\t6,  // [6:6] is the sub-list for extension extendee\n\t0,  // [0:6] is the sub-list for field type_name\n}\n\nfunc init() { file_artifact_proto_init() }\nfunc file_artifact_proto_init() {\n\tif File_artifact_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_artifact_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*CreateArtifactRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*CreateArtifactResponse); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*FinalizeArtifactRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*FinalizeArtifactResponse); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ListArtifactsRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ListArtifactsResponse); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ListArtifactsResponse_MonolithArtifact); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*GetSignedArtifactURLRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*GetSignedArtifactURLResponse); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*DeleteArtifactRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_artifact_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*DeleteArtifactResponse); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_artifact_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   11,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_artifact_proto_goTypes,\n\t\tDependencyIndexes: file_artifact_proto_depIdxs,\n\t\tMessageInfos:      file_artifact_proto_msgTypes,\n\t}.Build()\n\tFile_artifact_proto = out.File\n\tfile_artifact_proto_rawDesc = nil\n\tfile_artifact_proto_goTypes = nil\n\tfile_artifact_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "pkg/artifacts/artifacts_v4.go",
    "content": "// Copyright 2024 The Gitea Authors. All rights reserved.\n// SPDX-License-Identifier: MIT\n\npackage artifacts\n\n// GitHub Actions Artifacts V4 API Simple Description\n//\n// 1. Upload artifact\n// 1.1. CreateArtifact\n// Post: /twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact\n// Request:\n// {\n//     \"workflow_run_backend_id\": \"21\",\n//     \"workflow_job_run_backend_id\": \"49\",\n//     \"name\": \"test\",\n//     \"version\": 4\n// }\n// Response:\n// {\n//     \"ok\": true,\n//     \"signedUploadUrl\": \"http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75\"\n// }\n// 1.2. Upload Zip Content to Blobstorage (unauthenticated request)\n// PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=block\n// 1.3. Continue Upload Zip Content to Blobstorage (unauthenticated request), repeat until everything is uploaded\n// PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=appendBlock\n// 1.4. Unknown xml payload to Blobstorage (unauthenticated request), ignored for now\n// PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=blockList\n// 1.5. FinalizeArtifact\n// Post: /twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact\n// Request\n// {\n//     \"workflow_run_backend_id\": \"21\",\n//     \"workflow_job_run_backend_id\": \"49\",\n//     \"name\": \"test\",\n//     \"size\": \"2097\",\n//     \"hash\": \"sha256:b6325614d5649338b87215d9536b3c0477729b8638994c74cdefacb020a2cad4\"\n// }\n// Response\n// {\n//     \"ok\": true,\n//     \"artifactId\": \"4\"\n// }\n// 2. Download artifact\n// 2.1. ListArtifacts and optionally filter by artifact exact name or id\n// Post: /twirp/github.actions.results.api.v1.ArtifactService/ListArtifacts\n// Request\n// {\n//     \"workflow_run_backend_id\": \"21\",\n//     \"workflow_job_run_backend_id\": \"49\",\n//     \"name_filter\": \"test\"\n// }\n// Response\n// {\n//     \"artifacts\": [\n//         {\n//             \"workflowRunBackendId\": \"21\",\n//             \"workflowJobRunBackendId\": \"49\",\n//             \"databaseId\": \"4\",\n//             \"name\": \"test\",\n//             \"size\": \"2093\",\n//             \"createdAt\": \"2024-01-23T00:13:28Z\"\n//         }\n//     ]\n// }\n// 2.2. GetSignedArtifactURL get the URL to download the artifact zip file of a specific artifact\n// Post: /twirp/github.actions.results.api.v1.ArtifactService/GetSignedArtifactURL\n// Request\n// {\n//     \"workflow_run_backend_id\": \"21\",\n//     \"workflow_job_run_backend_id\": \"49\",\n//     \"name\": \"test\"\n// }\n// Response\n// {\n//     \"signedUrl\": \"http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/DownloadArtifact?sig=wHzFOwpF-6220-5CA0CIRmAX9VbiTC2Mji89UOqo1E8=&expires=2024-01-23+21%3A51%3A56.872846295+%2B0100+CET&artifactName=test&taskID=76\"\n// }\n// 2.3. Download Zip from Blobstorage (unauthenticated request)\n// GET: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/DownloadArtifact?sig=wHzFOwpF-6220-5CA0CIRmAX9VbiTC2Mji89UOqo1E8=&expires=2024-01-23+21%3A51%3A56.872846295+%2B0100+CET&artifactName=test&taskID=76\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash/fnv\"\n\t\"io\"\n\t\"io/fs\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/julienschmidt/httprouter\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/types/known/timestamppb\"\n)\n\nconst (\n\tArtifactV4RouteBase       = \"/twirp/github.actions.results.api.v1.ArtifactService\"\n\tArtifactV4ContentEncoding = \"application/zip\"\n)\n\ntype artifactV4Routes struct {\n\tprefix  string\n\tfs      WriteFS\n\trfs     fs.FS\n\tAppURL  string\n\tbaseDir string\n}\n\ntype ArtifactContext struct {\n\tReq  *http.Request\n\tResp http.ResponseWriter\n}\n\nfunc artifactNameToID(s string) int64 {\n\th := fnv.New32a()\n\th.Write([]byte(s))\n\treturn int64(h.Sum32())\n}\n\nfunc (c ArtifactContext) Error(status int, _ ...interface{}) {\n\tc.Resp.WriteHeader(status)\n}\n\nfunc (c ArtifactContext) JSON(status int, _ ...interface{}) {\n\tc.Resp.WriteHeader(status)\n}\n\nfunc validateRunIDV4(ctx *ArtifactContext, rawRunID string) (interface{}, int64, bool) {\n\trunID, err := strconv.ParseInt(rawRunID, 10, 64)\n\tif err != nil /* || task.Job.RunID != runID*/ {\n\t\tlog.Error(\"Error runID not match\")\n\t\tctx.Error(http.StatusBadRequest, \"run-id does not match\")\n\t\treturn nil, 0, false\n\t}\n\treturn nil, runID, true\n}\n\nfunc RoutesV4(router *httprouter.Router, baseDir string, fsys WriteFS, rfs fs.FS) {\n\troute := &artifactV4Routes{\n\t\tfs:      fsys,\n\t\trfs:     rfs,\n\t\tbaseDir: baseDir,\n\t\tprefix:  ArtifactV4RouteBase,\n\t}\n\trouter.POST(path.Join(ArtifactV4RouteBase, \"CreateArtifact\"), func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\t\troute.AppURL = r.Host\n\t\troute.createArtifact(&ArtifactContext{\n\t\t\tReq:  r,\n\t\t\tResp: w,\n\t\t})\n\t})\n\trouter.POST(path.Join(ArtifactV4RouteBase, \"FinalizeArtifact\"), func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\t\troute.finalizeArtifact(&ArtifactContext{\n\t\t\tReq:  r,\n\t\t\tResp: w,\n\t\t})\n\t})\n\trouter.POST(path.Join(ArtifactV4RouteBase, \"ListArtifacts\"), func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\t\troute.listArtifacts(&ArtifactContext{\n\t\t\tReq:  r,\n\t\t\tResp: w,\n\t\t})\n\t})\n\trouter.POST(path.Join(ArtifactV4RouteBase, \"GetSignedArtifactURL\"), func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\t\troute.AppURL = r.Host\n\t\troute.getSignedArtifactURL(&ArtifactContext{\n\t\t\tReq:  r,\n\t\t\tResp: w,\n\t\t})\n\t})\n\trouter.POST(path.Join(ArtifactV4RouteBase, \"DeleteArtifact\"), func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\t\troute.AppURL = r.Host\n\t\troute.deleteArtifact(&ArtifactContext{\n\t\t\tReq:  r,\n\t\t\tResp: w,\n\t\t})\n\t})\n\trouter.PUT(path.Join(ArtifactV4RouteBase, \"UploadArtifact\"), func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\t\troute.uploadArtifact(&ArtifactContext{\n\t\t\tReq:  r,\n\t\t\tResp: w,\n\t\t})\n\t})\n\trouter.GET(path.Join(ArtifactV4RouteBase, \"DownloadArtifact\"), func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {\n\t\troute.downloadArtifact(&ArtifactContext{\n\t\t\tReq:  r,\n\t\t\tResp: w,\n\t\t})\n\t})\n}\n\nfunc (r artifactV4Routes) buildSignature(endp, expires, artifactName string, taskID int64) []byte {\n\tmac := hmac.New(sha256.New, []byte{0xba, 0xdb, 0xee, 0xf0})\n\tmac.Write([]byte(endp))\n\tmac.Write([]byte(expires))\n\tmac.Write([]byte(artifactName))\n\tmac.Write([]byte(fmt.Sprint(taskID)))\n\treturn mac.Sum(nil)\n}\n\nfunc (r artifactV4Routes) buildArtifactURL(endp, artifactName string, taskID int64) string {\n\texpires := time.Now().Add(60 * time.Minute).Format(\"2006-01-02 15:04:05.999999999 -0700 MST\")\n\tuploadURL := \"http://\" + strings.TrimSuffix(r.AppURL, \"/\") + strings.TrimSuffix(r.prefix, \"/\") +\n\t\t\"/\" + endp + \"?sig=\" + base64.URLEncoding.EncodeToString(r.buildSignature(endp, expires, artifactName, taskID)) + \"&expires=\" + url.QueryEscape(expires) + \"&artifactName=\" + url.QueryEscape(artifactName) + \"&taskID=\" + fmt.Sprint(taskID)\n\treturn uploadURL\n}\n\nfunc (r artifactV4Routes) verifySignature(ctx *ArtifactContext, endp string) (int64, string, bool) {\n\trawTaskID := ctx.Req.URL.Query().Get(\"taskID\")\n\tsig := ctx.Req.URL.Query().Get(\"sig\")\n\texpires := ctx.Req.URL.Query().Get(\"expires\")\n\tartifactName := ctx.Req.URL.Query().Get(\"artifactName\")\n\tdsig, _ := base64.URLEncoding.DecodeString(sig)\n\ttaskID, _ := strconv.ParseInt(rawTaskID, 10, 64)\n\n\texpecedsig := r.buildSignature(endp, expires, artifactName, taskID)\n\tif !hmac.Equal(dsig, expecedsig) {\n\t\tlog.Error(\"Error unauthorized\")\n\t\tctx.Error(http.StatusUnauthorized, \"Error unauthorized\")\n\t\treturn -1, \"\", false\n\t}\n\tt, err := time.Parse(\"2006-01-02 15:04:05.999999999 -0700 MST\", expires)\n\tif err != nil || t.Before(time.Now()) {\n\t\tlog.Error(\"Error link expired\")\n\t\tctx.Error(http.StatusUnauthorized, \"Error link expired\")\n\t\treturn -1, \"\", false\n\t}\n\treturn taskID, artifactName, true\n}\n\nfunc (r *artifactV4Routes) parseProtbufBody(ctx *ArtifactContext, req protoreflect.ProtoMessage) bool {\n\tbody, err := io.ReadAll(ctx.Req.Body)\n\tif err != nil {\n\t\tlog.Errorf(\"Error decode request body: %v\", err)\n\t\tctx.Error(http.StatusInternalServerError, \"Error decode request body\")\n\t\treturn false\n\t}\n\terr = protojson.Unmarshal(body, req)\n\tif err != nil {\n\t\tlog.Errorf(\"Error decode request body: %v\", err)\n\t\tctx.Error(http.StatusInternalServerError, \"Error decode request body\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (r *artifactV4Routes) sendProtbufBody(ctx *ArtifactContext, req protoreflect.ProtoMessage) {\n\tresp, err := protojson.Marshal(req)\n\tif err != nil {\n\t\tlog.Errorf(\"Error encode response body: %v\", err)\n\t\tctx.Error(http.StatusInternalServerError, \"Error encode response body\")\n\t\treturn\n\t}\n\tctx.Resp.Header().Set(\"Content-Type\", \"application/json;charset=utf-8\")\n\tctx.Resp.WriteHeader(http.StatusOK)\n\t_, _ = ctx.Resp.Write(resp)\n}\n\nfunc (r *artifactV4Routes) createArtifact(ctx *ArtifactContext) {\n\tvar req CreateArtifactRequest\n\n\tif ok := r.parseProtbufBody(ctx, &req); !ok {\n\t\treturn\n\t}\n\t_, runID, ok := validateRunIDV4(ctx, req.WorkflowRunBackendId)\n\tif !ok {\n\t\treturn\n\t}\n\n\tartifactName := req.Name\n\n\tsafeRunPath := safeResolve(r.baseDir, fmt.Sprint(runID))\n\tsafePath := safeResolve(safeRunPath, artifactName)\n\tsafePath = safeResolve(safePath, artifactName+\".zip\")\n\tfile, err := r.fs.OpenWritable(safePath)\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfile.Close()\n\n\trespData := CreateArtifactResponse{\n\t\tOk:              true,\n\t\tSignedUploadUrl: r.buildArtifactURL(\"UploadArtifact\", artifactName, runID),\n\t}\n\tr.sendProtbufBody(ctx, &respData)\n}\n\nfunc (r *artifactV4Routes) uploadArtifact(ctx *ArtifactContext) {\n\ttask, artifactName, ok := r.verifySignature(ctx, \"UploadArtifact\")\n\tif !ok {\n\t\treturn\n\t}\n\n\tcomp := ctx.Req.URL.Query().Get(\"comp\")\n\tswitch comp {\n\tcase \"block\", \"appendBlock\":\n\n\t\tsafeRunPath := safeResolve(r.baseDir, fmt.Sprint(task))\n\t\tsafePath := safeResolve(safeRunPath, artifactName)\n\t\tsafePath = safeResolve(safePath, artifactName+\".zip\")\n\n\t\tfile, err := r.fs.OpenAppendable(safePath)\n\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tdefer file.Close()\n\n\t\twriter, ok := file.(io.Writer)\n\t\tif !ok {\n\t\t\tpanic(errors.New(\"File is not writable\"))\n\t\t}\n\n\t\tif ctx.Req.Body == nil {\n\t\t\tpanic(errors.New(\"No body given\"))\n\t\t}\n\n\t\t_, err = io.Copy(writer, ctx.Req.Body)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tfile.Close()\n\t\tctx.JSON(http.StatusCreated, \"appended\")\n\tcase \"blocklist\":\n\t\tctx.JSON(http.StatusCreated, \"created\")\n\t}\n}\n\nfunc (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) {\n\tvar req FinalizeArtifactRequest\n\n\tif ok := r.parseProtbufBody(ctx, &req); !ok {\n\t\treturn\n\t}\n\t_, _, ok := validateRunIDV4(ctx, req.WorkflowRunBackendId)\n\tif !ok {\n\t\treturn\n\t}\n\n\trespData := FinalizeArtifactResponse{\n\t\tOk:         true,\n\t\tArtifactId: artifactNameToID(req.Name),\n\t}\n\tr.sendProtbufBody(ctx, &respData)\n}\n\nfunc (r *artifactV4Routes) listArtifacts(ctx *ArtifactContext) {\n\tvar req ListArtifactsRequest\n\n\tif ok := r.parseProtbufBody(ctx, &req); !ok {\n\t\treturn\n\t}\n\t_, runID, ok := validateRunIDV4(ctx, req.WorkflowRunBackendId)\n\tif !ok {\n\t\treturn\n\t}\n\n\tsafePath := safeResolve(r.baseDir, fmt.Sprint(runID))\n\n\tentries, err := fs.ReadDir(r.rfs, safePath)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tlist := []*ListArtifactsResponse_MonolithArtifact{}\n\n\tfor _, entry := range entries {\n\t\tid := artifactNameToID(entry.Name())\n\t\tif (req.NameFilter == nil || req.NameFilter.Value == entry.Name()) && (req.IdFilter == nil || req.IdFilter.Value == id) {\n\t\t\tdata := &ListArtifactsResponse_MonolithArtifact{\n\t\t\t\tName:                    entry.Name(),\n\t\t\t\tCreatedAt:               timestamppb.Now(),\n\t\t\t\tDatabaseId:              id,\n\t\t\t\tWorkflowRunBackendId:    req.WorkflowRunBackendId,\n\t\t\t\tWorkflowJobRunBackendId: req.WorkflowJobRunBackendId,\n\t\t\t\tSize:                    0,\n\t\t\t}\n\t\t\tif info, err := entry.Info(); err == nil {\n\t\t\t\tdata.Size = info.Size()\n\t\t\t\tdata.CreatedAt = timestamppb.New(info.ModTime())\n\t\t\t}\n\t\t\tlist = append(list, data)\n\t\t}\n\t}\n\n\trespData := ListArtifactsResponse{\n\t\tArtifacts: list,\n\t}\n\tr.sendProtbufBody(ctx, &respData)\n}\n\nfunc (r *artifactV4Routes) getSignedArtifactURL(ctx *ArtifactContext) {\n\tvar req GetSignedArtifactURLRequest\n\n\tif ok := r.parseProtbufBody(ctx, &req); !ok {\n\t\treturn\n\t}\n\t_, runID, ok := validateRunIDV4(ctx, req.WorkflowRunBackendId)\n\tif !ok {\n\t\treturn\n\t}\n\n\tartifactName := req.Name\n\n\trespData := GetSignedArtifactURLResponse{}\n\n\trespData.SignedUrl = r.buildArtifactURL(\"DownloadArtifact\", artifactName, runID)\n\tr.sendProtbufBody(ctx, &respData)\n}\n\nfunc (r *artifactV4Routes) downloadArtifact(ctx *ArtifactContext) {\n\ttask, artifactName, ok := r.verifySignature(ctx, \"DownloadArtifact\")\n\tif !ok {\n\t\treturn\n\t}\n\n\tsafeRunPath := safeResolve(r.baseDir, fmt.Sprint(task))\n\tsafePath := safeResolve(safeRunPath, artifactName)\n\tsafePath = safeResolve(safePath, artifactName+\".zip\")\n\n\tfile, _ := r.rfs.Open(safePath)\n\n\t_, _ = io.Copy(ctx.Resp, file)\n}\n\nfunc (r *artifactV4Routes) deleteArtifact(ctx *ArtifactContext) {\n\tvar req DeleteArtifactRequest\n\n\tif ok := r.parseProtbufBody(ctx, &req); !ok {\n\t\treturn\n\t}\n\t_, runID, ok := validateRunIDV4(ctx, req.WorkflowRunBackendId)\n\tif !ok {\n\t\treturn\n\t}\n\tsafeRunPath := safeResolve(r.baseDir, fmt.Sprint(runID))\n\tsafePath := safeResolve(safeRunPath, req.Name)\n\n\t_ = os.RemoveAll(safePath)\n\n\trespData := DeleteArtifactResponse{\n\t\tOk:         true,\n\t\tArtifactId: artifactNameToID(req.Name),\n\t}\n\tr.sendProtbufBody(ctx, &respData)\n}\n"
  },
  {
    "path": "pkg/artifacts/server.go",
    "content": "package artifacts\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/julienschmidt/httprouter\"\n\n\t\"github.com/nektos/act/pkg/common\"\n)\n\ntype FileContainerResourceURL struct {\n\tFileContainerResourceURL string `json:\"fileContainerResourceUrl\"`\n}\n\ntype NamedFileContainerResourceURL struct {\n\tName                     string `json:\"name\"`\n\tFileContainerResourceURL string `json:\"fileContainerResourceUrl\"`\n}\n\ntype NamedFileContainerResourceURLResponse struct {\n\tCount int                             `json:\"count\"`\n\tValue []NamedFileContainerResourceURL `json:\"value\"`\n}\n\ntype ContainerItem struct {\n\tPath            string `json:\"path\"`\n\tItemType        string `json:\"itemType\"`\n\tContentLocation string `json:\"contentLocation\"`\n}\n\ntype ContainerItemResponse struct {\n\tValue []ContainerItem `json:\"value\"`\n}\n\ntype ResponseMessage struct {\n\tMessage string `json:\"message\"`\n}\n\ntype WritableFile interface {\n\tio.WriteCloser\n}\n\ntype WriteFS interface {\n\tOpenWritable(name string) (WritableFile, error)\n\tOpenAppendable(name string) (WritableFile, error)\n}\n\ntype readWriteFSImpl struct {\n}\n\nfunc (fwfs readWriteFSImpl) Open(name string) (fs.File, error) {\n\treturn os.Open(name)\n}\n\nfunc (fwfs readWriteFSImpl) OpenWritable(name string) (WritableFile, error) {\n\tif err := os.MkdirAll(filepath.Dir(name), os.ModePerm); err != nil {\n\t\treturn nil, err\n\t}\n\treturn os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o644)\n}\n\nfunc (fwfs readWriteFSImpl) OpenAppendable(name string) (WritableFile, error) {\n\tif err := os.MkdirAll(filepath.Dir(name), os.ModePerm); err != nil {\n\t\treturn nil, err\n\t}\n\tfile, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR, 0o644)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, err = file.Seek(0, io.SeekEnd)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn file, nil\n}\n\nvar gzipExtension = \".gz__\"\n\nfunc safeResolve(baseDir string, relPath string) string {\n\treturn filepath.Join(baseDir, filepath.Clean(filepath.Join(string(os.PathSeparator), relPath)))\n}\n\nfunc uploads(router *httprouter.Router, baseDir string, fsys WriteFS) {\n\trouter.POST(\"/_apis/pipelines/workflows/:runId/artifacts\", func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {\n\t\trunID := params.ByName(\"runId\")\n\n\t\tjson, err := json.Marshal(FileContainerResourceURL{\n\t\t\tFileContainerResourceURL: fmt.Sprintf(\"http://%s/upload/%s\", req.Host, runID),\n\t\t})\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\t_, err = w.Write(json)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t})\n\n\trouter.PUT(\"/upload/:runId\", func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {\n\t\titemPath := req.URL.Query().Get(\"itemPath\")\n\t\trunID := params.ByName(\"runId\")\n\n\t\tif req.Header.Get(\"Content-Encoding\") == \"gzip\" {\n\t\t\titemPath += gzipExtension\n\t\t}\n\n\t\tsafeRunPath := safeResolve(baseDir, runID)\n\t\tsafePath := safeResolve(safeRunPath, itemPath)\n\n\t\tfile, err := func() (WritableFile, error) {\n\t\t\tcontentRange := req.Header.Get(\"Content-Range\")\n\t\t\tif contentRange != \"\" && !strings.HasPrefix(contentRange, \"bytes 0-\") {\n\t\t\t\treturn fsys.OpenAppendable(safePath)\n\t\t\t}\n\t\t\treturn fsys.OpenWritable(safePath)\n\t\t}()\n\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tdefer file.Close()\n\n\t\twriter, ok := file.(io.Writer)\n\t\tif !ok {\n\t\t\tpanic(errors.New(\"File is not writable\"))\n\t\t}\n\n\t\tif req.Body == nil {\n\t\t\tpanic(errors.New(\"No body given\"))\n\t\t}\n\n\t\t_, err = io.Copy(writer, req.Body)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tjson, err := json.Marshal(ResponseMessage{\n\t\t\tMessage: \"success\",\n\t\t})\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\t_, err = w.Write(json)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t})\n\n\trouter.PATCH(\"/_apis/pipelines/workflows/:runId/artifacts\", func(w http.ResponseWriter, _ *http.Request, _ httprouter.Params) {\n\t\tjson, err := json.Marshal(ResponseMessage{\n\t\t\tMessage: \"success\",\n\t\t})\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\t_, err = w.Write(json)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t})\n}\n\nfunc downloads(router *httprouter.Router, baseDir string, fsys fs.FS) {\n\trouter.GET(\"/_apis/pipelines/workflows/:runId/artifacts\", func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {\n\t\trunID := params.ByName(\"runId\")\n\n\t\tsafePath := safeResolve(baseDir, runID)\n\n\t\tentries, err := fs.ReadDir(fsys, safePath)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tvar list []NamedFileContainerResourceURL\n\t\tfor _, entry := range entries {\n\t\t\tlist = append(list, NamedFileContainerResourceURL{\n\t\t\t\tName:                     entry.Name(),\n\t\t\t\tFileContainerResourceURL: fmt.Sprintf(\"http://%s/download/%s\", req.Host, runID),\n\t\t\t})\n\t\t}\n\n\t\tjson, err := json.Marshal(NamedFileContainerResourceURLResponse{\n\t\t\tCount: len(list),\n\t\t\tValue: list,\n\t\t})\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\t_, err = w.Write(json)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t})\n\n\trouter.GET(\"/download/:container\", func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {\n\t\tcontainer := params.ByName(\"container\")\n\t\titemPath := req.URL.Query().Get(\"itemPath\")\n\t\tsafePath := safeResolve(baseDir, filepath.Join(container, itemPath))\n\n\t\tvar files []ContainerItem\n\t\terr := fs.WalkDir(fsys, safePath, func(path string, entry fs.DirEntry, _ error) error {\n\t\t\tif !entry.IsDir() {\n\t\t\t\trel, err := filepath.Rel(safePath, path)\n\t\t\t\tif err != nil {\n\t\t\t\t\tpanic(err)\n\t\t\t\t}\n\n\t\t\t\t// if it was upload as gzip\n\t\t\t\trel = strings.TrimSuffix(rel, gzipExtension)\n\t\t\t\tpath := filepath.Join(itemPath, rel)\n\n\t\t\t\trel = filepath.ToSlash(rel)\n\t\t\t\tpath = filepath.ToSlash(path)\n\n\t\t\t\tfiles = append(files, ContainerItem{\n\t\t\t\t\tPath:            path,\n\t\t\t\t\tItemType:        \"file\",\n\t\t\t\t\tContentLocation: fmt.Sprintf(\"http://%s/artifact/%s/%s/%s\", req.Host, container, itemPath, rel),\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tjson, err := json.Marshal(ContainerItemResponse{\n\t\t\tValue: files,\n\t\t})\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\t_, err = w.Write(json)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t})\n\n\trouter.GET(\"/artifact/*path\", func(w http.ResponseWriter, _ *http.Request, params httprouter.Params) {\n\t\tpath := params.ByName(\"path\")[1:]\n\n\t\tsafePath := safeResolve(baseDir, path)\n\n\t\tfile, err := fsys.Open(safePath)\n\t\tif err != nil {\n\t\t\t// try gzip file\n\t\t\tfile, err = fsys.Open(safePath + gzipExtension)\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\tw.Header().Add(\"Content-Encoding\", \"gzip\")\n\t\t}\n\n\t\t_, err = io.Copy(w, file)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t})\n}\n\nfunc Serve(ctx context.Context, artifactPath string, addr string, port string) context.CancelFunc {\n\tserverContext, cancel := context.WithCancel(ctx)\n\tlogger := common.Logger(serverContext)\n\n\tif artifactPath == \"\" {\n\t\treturn cancel\n\t}\n\n\trouter := httprouter.New()\n\n\tlogger.Debugf(\"Artifacts base path '%s'\", artifactPath)\n\tfsys := readWriteFSImpl{}\n\tuploads(router, artifactPath, fsys)\n\tdownloads(router, artifactPath, fsys)\n\tRoutesV4(router, artifactPath, fsys, fsys)\n\n\tserver := &http.Server{\n\t\tAddr:              fmt.Sprintf(\"%s:%s\", addr, port),\n\t\tReadHeaderTimeout: 2 * time.Second,\n\t\tHandler:           router,\n\t}\n\n\t// run server\n\tgo func() {\n\t\tlogger.Infof(\"Start server on http://%s:%s\", addr, port)\n\t\tif err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {\n\t\t\tlogger.Fatal(err)\n\t\t}\n\t}()\n\n\t// wait for cancel to gracefully shutdown server\n\tgo func() {\n\t\t<-serverContext.Done()\n\n\t\tif err := server.Shutdown(ctx); err != nil {\n\t\t\tlogger.Errorf(\"Failed shutdown gracefully - force shutdown: %v\", err)\n\t\t\tserver.Close()\n\t\t}\n\t}()\n\n\treturn cancel\n}\n"
  },
  {
    "path": "pkg/artifacts/server_test.go",
    "content": "package artifacts\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\t\"testing/fstest\"\n\n\t\"github.com/julienschmidt/httprouter\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/nektos/act/pkg/runner\"\n)\n\ntype writableMapFile struct {\n\tfstest.MapFile\n}\n\nfunc (f *writableMapFile) Write(data []byte) (int, error) {\n\tf.Data = data\n\treturn len(data), nil\n}\n\nfunc (f *writableMapFile) Close() error {\n\treturn nil\n}\n\ntype writeMapFS struct {\n\tfstest.MapFS\n}\n\nfunc (fsys writeMapFS) OpenWritable(name string) (WritableFile, error) {\n\tvar file = &writableMapFile{\n\t\tMapFile: fstest.MapFile{\n\t\t\tData: []byte(\"content2\"),\n\t\t},\n\t}\n\tfsys.MapFS[name] = &file.MapFile\n\n\treturn file, nil\n}\n\nfunc (fsys writeMapFS) OpenAppendable(name string) (WritableFile, error) {\n\tvar file = &writableMapFile{\n\t\tMapFile: fstest.MapFile{\n\t\t\tData: []byte(\"content2\"),\n\t\t},\n\t}\n\tfsys.MapFS[name] = &file.MapFile\n\n\treturn file, nil\n}\n\nfunc TestNewArtifactUploadPrepare(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar memfs = fstest.MapFS(map[string]*fstest.MapFile{})\n\n\trouter := httprouter.New()\n\tuploads(router, \"artifact/server/path\", writeMapFS{memfs})\n\n\treq, _ := http.NewRequest(\"POST\", \"http://localhost/_apis/pipelines/workflows/1/artifacts\", nil)\n\trr := httptest.NewRecorder()\n\n\trouter.ServeHTTP(rr, req)\n\n\tif status := rr.Code; status != http.StatusOK {\n\t\tassert.Fail(\"Wrong status\")\n\t}\n\n\tresponse := FileContainerResourceURL{}\n\terr := json.Unmarshal(rr.Body.Bytes(), &response)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tassert.Equal(\"http://localhost/upload/1\", response.FileContainerResourceURL)\n}\n\nfunc TestArtifactUploadBlob(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar memfs = fstest.MapFS(map[string]*fstest.MapFile{})\n\n\trouter := httprouter.New()\n\tuploads(router, \"artifact/server/path\", writeMapFS{memfs})\n\n\treq, _ := http.NewRequest(\"PUT\", \"http://localhost/upload/1?itemPath=some/file\", strings.NewReader(\"content\"))\n\trr := httptest.NewRecorder()\n\n\trouter.ServeHTTP(rr, req)\n\n\tif status := rr.Code; status != http.StatusOK {\n\t\tassert.Fail(\"Wrong status\")\n\t}\n\n\tresponse := ResponseMessage{}\n\terr := json.Unmarshal(rr.Body.Bytes(), &response)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tassert.Equal(\"success\", response.Message)\n\tassert.Equal(\"content\", string(memfs[\"artifact/server/path/1/some/file\"].Data))\n}\n\nfunc TestFinalizeArtifactUpload(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar memfs = fstest.MapFS(map[string]*fstest.MapFile{})\n\n\trouter := httprouter.New()\n\tuploads(router, \"artifact/server/path\", writeMapFS{memfs})\n\n\treq, _ := http.NewRequest(\"PATCH\", \"http://localhost/_apis/pipelines/workflows/1/artifacts\", nil)\n\trr := httptest.NewRecorder()\n\n\trouter.ServeHTTP(rr, req)\n\n\tif status := rr.Code; status != http.StatusOK {\n\t\tassert.Fail(\"Wrong status\")\n\t}\n\n\tresponse := ResponseMessage{}\n\terr := json.Unmarshal(rr.Body.Bytes(), &response)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tassert.Equal(\"success\", response.Message)\n}\n\nfunc TestListArtifacts(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar memfs = fstest.MapFS(map[string]*fstest.MapFile{\n\t\t\"artifact/server/path/1/file.txt\": {\n\t\t\tData: []byte(\"\"),\n\t\t},\n\t})\n\n\trouter := httprouter.New()\n\tdownloads(router, \"artifact/server/path\", memfs)\n\n\treq, _ := http.NewRequest(\"GET\", \"http://localhost/_apis/pipelines/workflows/1/artifacts\", nil)\n\trr := httptest.NewRecorder()\n\n\trouter.ServeHTTP(rr, req)\n\n\tif status := rr.Code; status != http.StatusOK {\n\t\tassert.FailNow(fmt.Sprintf(\"Wrong status: %d\", status))\n\t}\n\n\tresponse := NamedFileContainerResourceURLResponse{}\n\terr := json.Unmarshal(rr.Body.Bytes(), &response)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tassert.Equal(1, response.Count)\n\tassert.Equal(\"file.txt\", response.Value[0].Name)\n\tassert.Equal(\"http://localhost/download/1\", response.Value[0].FileContainerResourceURL)\n}\n\nfunc TestListArtifactContainer(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar memfs = fstest.MapFS(map[string]*fstest.MapFile{\n\t\t\"artifact/server/path/1/some/file\": {\n\t\t\tData: []byte(\"\"),\n\t\t},\n\t})\n\n\trouter := httprouter.New()\n\tdownloads(router, \"artifact/server/path\", memfs)\n\n\treq, _ := http.NewRequest(\"GET\", \"http://localhost/download/1?itemPath=some/file\", nil)\n\trr := httptest.NewRecorder()\n\n\trouter.ServeHTTP(rr, req)\n\n\tif status := rr.Code; status != http.StatusOK {\n\t\tassert.FailNow(fmt.Sprintf(\"Wrong status: %d\", status))\n\t}\n\n\tresponse := ContainerItemResponse{}\n\terr := json.Unmarshal(rr.Body.Bytes(), &response)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tassert.Equal(1, len(response.Value))\n\tassert.Equal(\"some/file\", response.Value[0].Path)\n\tassert.Equal(\"file\", response.Value[0].ItemType)\n\tassert.Equal(\"http://localhost/artifact/1/some/file/.\", response.Value[0].ContentLocation)\n}\n\nfunc TestDownloadArtifactFile(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar memfs = fstest.MapFS(map[string]*fstest.MapFile{\n\t\t\"artifact/server/path/1/some/file\": {\n\t\t\tData: []byte(\"content\"),\n\t\t},\n\t})\n\n\trouter := httprouter.New()\n\tdownloads(router, \"artifact/server/path\", memfs)\n\n\treq, _ := http.NewRequest(\"GET\", \"http://localhost/artifact/1/some/file\", nil)\n\trr := httptest.NewRecorder()\n\n\trouter.ServeHTTP(rr, req)\n\n\tif status := rr.Code; status != http.StatusOK {\n\t\tassert.FailNow(fmt.Sprintf(\"Wrong status: %d\", status))\n\t}\n\n\tdata := rr.Body.Bytes()\n\n\tassert.Equal(\"content\", string(data))\n}\n\ntype TestJobFileInfo struct {\n\tworkdir               string\n\tworkflowPath          string\n\teventName             string\n\terrorMessage          string\n\tplatforms             map[string]string\n\tcontainerArchitecture string\n}\n\nvar (\n\tartifactsPath = path.Join(os.TempDir(), \"test-artifacts\")\n\tartifactsAddr = \"127.0.0.1\"\n\tartifactsPort = \"12345\"\n)\n\nfunc TestArtifactFlow(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\tctx := context.Background()\n\n\tcancel := Serve(ctx, artifactsPath, artifactsAddr, artifactsPort)\n\tdefer cancel()\n\n\tplatforms := map[string]string{\n\t\t\"ubuntu-latest\": \"node:16-buster\", // Don't use node:16-buster-slim because it doesn't have curl command, which is used in the tests\n\t}\n\n\ttables := []TestJobFileInfo{\n\t\t{\"testdata\", \"upload-and-download\", \"push\", \"\", platforms, \"\"},\n\t\t{\"testdata\", \"GHSL-2023-004\", \"push\", \"\", platforms, \"\"},\n\t\t{\"testdata\", \"v4\", \"push\", \"\", platforms, \"\"},\n\t}\n\tlog.SetLevel(log.DebugLevel)\n\n\tfor _, table := range tables {\n\t\trunTestJobFile(ctx, t, table)\n\t}\n}\n\nfunc runTestJobFile(ctx context.Context, t *testing.T, tjfi TestJobFileInfo) {\n\tt.Run(tjfi.workflowPath, func(t *testing.T) {\n\t\tfmt.Printf(\"::group::%s\\n\", tjfi.workflowPath)\n\n\t\tif err := os.RemoveAll(artifactsPath); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tworkdir, err := filepath.Abs(tjfi.workdir)\n\t\tassert.Nil(t, err, workdir)\n\t\tfullWorkflowPath := filepath.Join(workdir, tjfi.workflowPath)\n\t\trunnerConfig := &runner.Config{\n\t\t\tWorkdir:               workdir,\n\t\t\tBindWorkdir:           false,\n\t\t\tEventName:             tjfi.eventName,\n\t\t\tPlatforms:             tjfi.platforms,\n\t\t\tReuseContainers:       false,\n\t\t\tContainerArchitecture: tjfi.containerArchitecture,\n\t\t\tGitHubInstance:        \"github.com\",\n\t\t\tArtifactServerPath:    artifactsPath,\n\t\t\tArtifactServerAddr:    artifactsAddr,\n\t\t\tArtifactServerPort:    artifactsPort,\n\t\t}\n\n\t\trunner, err := runner.New(runnerConfig)\n\t\tassert.Nil(t, err, tjfi.workflowPath)\n\n\t\tplanner, err := model.NewWorkflowPlanner(fullWorkflowPath, true, false)\n\t\tassert.Nil(t, err, fullWorkflowPath)\n\n\t\tplan, err := planner.PlanEvent(tjfi.eventName)\n\t\tif err == nil {\n\t\t\terr = runner.NewPlanExecutor(plan)(ctx)\n\t\t\tif tjfi.errorMessage == \"\" {\n\t\t\t\tassert.Nil(t, err, fullWorkflowPath)\n\t\t\t} else {\n\t\t\t\tassert.Error(t, err, tjfi.errorMessage)\n\t\t\t}\n\t\t} else {\n\t\t\tassert.Nil(t, plan)\n\t\t}\n\n\t\tfmt.Println(\"::endgroup::\")\n\t})\n}\n\nfunc TestMkdirFsImplSafeResolve(t *testing.T) {\n\tbaseDir := \"/foo/bar\"\n\n\ttests := map[string]struct {\n\t\tinput string\n\t\twant  string\n\t}{\n\t\t\"simple\":         {input: \"baz\", want: \"/foo/bar/baz\"},\n\t\t\"nested\":         {input: \"baz/blue\", want: \"/foo/bar/baz/blue\"},\n\t\t\"dots in middle\": {input: \"baz/../../blue\", want: \"/foo/bar/blue\"},\n\t\t\"leading dots\":   {input: \"../../parent\", want: \"/foo/bar/parent\"},\n\t\t\"root path\":      {input: \"/root\", want: \"/foo/bar/root\"},\n\t\t\"root\":           {input: \"/\", want: \"/foo/bar\"},\n\t\t\"empty\":          {input: \"\", want: \"/foo/bar\"},\n\t}\n\n\tfor name, tc := range tests {\n\t\tt.Run(name, func(t *testing.T) {\n\t\t\tassert := assert.New(t)\n\t\t\tassert.Equal(tc.want, safeResolve(baseDir, tc.input))\n\t\t})\n\t}\n}\n\nfunc TestDownloadArtifactFileUnsafePath(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar memfs = fstest.MapFS(map[string]*fstest.MapFile{\n\t\t\"artifact/server/path/some/file\": {\n\t\t\tData: []byte(\"content\"),\n\t\t},\n\t})\n\n\trouter := httprouter.New()\n\tdownloads(router, \"artifact/server/path\", memfs)\n\n\treq, _ := http.NewRequest(\"GET\", \"http://localhost/artifact/2/../../some/file\", nil)\n\trr := httptest.NewRecorder()\n\n\trouter.ServeHTTP(rr, req)\n\n\tif status := rr.Code; status != http.StatusOK {\n\t\tassert.FailNow(fmt.Sprintf(\"Wrong status: %d\", status))\n\t}\n\n\tdata := rr.Body.Bytes()\n\n\tassert.Equal(\"content\", string(data))\n}\n\nfunc TestArtifactUploadBlobUnsafePath(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar memfs = fstest.MapFS(map[string]*fstest.MapFile{})\n\n\trouter := httprouter.New()\n\tuploads(router, \"artifact/server/path\", writeMapFS{memfs})\n\n\treq, _ := http.NewRequest(\"PUT\", \"http://localhost/upload/1?itemPath=../../some/file\", strings.NewReader(\"content\"))\n\trr := httptest.NewRecorder()\n\n\trouter.ServeHTTP(rr, req)\n\n\tif status := rr.Code; status != http.StatusOK {\n\t\tassert.Fail(\"Wrong status\")\n\t}\n\n\tresponse := ResponseMessage{}\n\terr := json.Unmarshal(rr.Body.Bytes(), &response)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tassert.Equal(\"success\", response.Message)\n\tassert.Equal(\"content\", string(memfs[\"artifact/server/path/1/some/file\"].Data))\n}\n"
  },
  {
    "path": "pkg/artifacts/testdata/GHSL-2023-004/artifacts.yml",
    "content": "\nname: \"GHSL-2023-0004\"\non: push\n\njobs:\n  test-artifacts:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"hello world\" > test.txt\n      - name: curl upload\n        run: curl --silent --show-error --fail ${ACTIONS_RUNTIME_URL}upload/1?itemPath=../../my-artifact/secret.txt --upload-file test.txt\n      - uses: actions/download-artifact@v2\n        with:\n          name: my-artifact\n          path: test-artifacts\n      - name: 'Verify Artifact #1'\n        run: |\n          file=\"test-artifacts/secret.txt\"\n          if [ ! -f $file ] ; then\n            echo \"Expected file does not exist\"\n            exit 1\n          fi\n          if [ \"$(cat $file)\" != \"hello world\" ] ; then\n            echo \"File contents of downloaded artifact are incorrect\"\n            exit 1\n          fi\n      - name: Verify download should work by clean extra dots\n        run: curl --silent --show-error --fail --path-as-is -o out.txt ${ACTIONS_RUNTIME_URL}artifact/1/../../../1/my-artifact/secret.txt\n      - name: 'Verify download content'\n        run: |\n          file=\"out.txt\"\n          if [ ! -f $file ] ; then\n            echo \"Expected file does not exist\"\n            exit 1\n          fi\n          if [ \"$(cat $file)\" != \"hello world\" ] ; then\n            echo \"File contents of downloaded artifact are incorrect\"\n            exit 1\n          fi\n"
  },
  {
    "path": "pkg/artifacts/testdata/upload-and-download/artifacts.yml",
    "content": "\nname: \"Test that artifact uploads and downloads succeed\"\non: push\n\njobs:\n  test-artifacts:\n    runs-on: ubuntu-latest\n    steps:\n      - run: mkdir -p path/to/artifact\n      - run: echo hello > path/to/artifact/world.txt\n      - uses: actions/upload-artifact@v2\n        with:\n          name: my-artifact\n          path: path/to/artifact/world.txt\n\n      - run: rm -rf path\n\n      - uses: actions/download-artifact@v2\n        with:\n          name: my-artifact\n      - name: Display structure of downloaded files\n        run: ls -la\n\n      # Test end-to-end by uploading two artifacts and then downloading them\n      - name: Create artifact files\n        run: |\n          mkdir -p path/to/dir-1\n          mkdir -p path/to/dir-2\n          mkdir -p path/to/dir-3\n          mkdir -p path/to/dir-5\n          mkdir -p path/to/dir-6\n          mkdir -p path/to/dir-7\n          echo \"Lorem ipsum dolor sit amet\" > path/to/dir-1/file1.txt\n          echo \"Hello world from file #2\" > path/to/dir-2/file2.txt\n          echo \"This is a going to be a test for a large enough file that should get compressed with GZip. The @actions/artifact package uses GZip to upload files. This text should have a compression ratio greater than 100% so it should get uploaded using GZip\" > path/to/dir-3/gzip.txt\n          dd if=/dev/random of=path/to/dir-5/file5.rnd bs=1024 count=1024\n          dd if=/dev/random of=path/to/dir-6/file6.rnd bs=1024 count=$((10*1024))\n          dd if=/dev/random of=path/to/dir-7/file7.rnd bs=1024 count=$((10*1024))\n\n      # Upload a single file artifact\n      - name: 'Upload artifact #1'\n        uses: actions/upload-artifact@v2\n        with:\n          name: 'Artifact-A'\n          path: path/to/dir-1/file1.txt\n      \n      # Upload using a wildcard pattern, name should default to 'artifact' if not provided\n      - name: 'Upload artifact #2'\n        uses: actions/upload-artifact@v2\n        with:\n          path: path/**/dir*/\n      \n      # Upload a directory that contains a file that will be uploaded with GZip\n      - name: 'Upload artifact #3'\n        uses: actions/upload-artifact@v2\n        with:\n          name: 'GZip-Artifact'\n          path: path/to/dir-3/\n      \n      # Upload a directory that contains a file that will be uploaded with GZip\n      - name: 'Upload artifact #4'\n        uses: actions/upload-artifact@v2\n        with:\n          name: 'Multi-Path-Artifact'\n          path: |\n            path/to/dir-1/*\n            path/to/dir-[23]/*\n            !path/to/dir-3/*.txt\n      \n      # Upload a mid-size file artifact\n      - name: 'Upload artifact #5'\n        uses: actions/upload-artifact@v2\n        with:\n          name: 'Mid-Size-Artifact'\n          path: path/to/dir-5/file5.rnd\n      \n      # Upload a big file artifact\n      - name: 'Upload artifact #6'\n        uses: actions/upload-artifact@v2\n        with:\n          name: 'Big-Artifact'\n          path: path/to/dir-6/file6.rnd\n\n      # Upload a big file artifact twice\n      - name: 'Upload artifact #7 (First)'\n        uses: actions/upload-artifact@v2\n        with:\n          name: 'Big-Uploaded-Twice'\n          path: path/to/dir-7/file7.rnd\n\n      # Upload a big file artifact twice\n      - name: 'Upload artifact #7 (Second)'\n        uses: actions/upload-artifact@v2\n        with:\n          name: 'Big-Uploaded-Twice'\n          path: path/to/dir-7/file7.rnd\n\n      # Verify artifacts. Switch to download-artifact@v2 once it's out of preview\n      \n      # Download Artifact #1 and verify the correctness of the content\n      - name: 'Download artifact #1'\n        uses: actions/download-artifact@v2\n        with:\n          name: 'Artifact-A'\n          path: some/new/path\n      \n      - name: 'Verify Artifact #1'\n        run: |\n          file=\"some/new/path/file1.txt\"\n          if [ ! -f $file ] ; then\n            echo \"Expected file does not exist\"\n            exit 1\n          fi\n          if [ \"$(cat $file)\" != \"Lorem ipsum dolor sit amet\" ] ; then\n            echo \"File contents of downloaded artifact are incorrect\"\n            exit 1\n          fi\n      \n      # Download Artifact #2 and verify the correctness of the content\n      - name: 'Download artifact #2'\n        uses: actions/download-artifact@v2\n        with:\n          name: 'artifact'\n          path: some/other/path\n      \n      - name: 'Verify Artifact #2'\n        run: |\n          file1=\"some/other/path/to/dir-1/file1.txt\"\n          file2=\"some/other/path/to/dir-2/file2.txt\"\n          if [ ! -f $file1 -o ! -f $file2 ] ; then\n            echo \"Expected files do not exist\"\n            exit 1\n          fi\n          if [ \"$(cat $file1)\" != \"Lorem ipsum dolor sit amet\" -o \"$(cat $file2)\" != \"Hello world from file #2\" ] ; then\n            echo \"File contents of downloaded artifacts are incorrect\"\n            exit 1\n          fi\n      \n      # Download Artifact #3 and verify the correctness of the content\n      - name: 'Download artifact #3'\n        uses: actions/download-artifact@v2\n        with:\n          name: 'GZip-Artifact'\n          path: gzip/artifact/path\n      \n      # Because a directory was used as input during the upload the parent directories, path/to/dir-3/, should not be included in the uploaded artifact\n      - name: 'Verify Artifact #3'\n        run: |\n          gzipFile=\"gzip/artifact/path/gzip.txt\"\n          if [ ! -f $gzipFile ] ; then\n            echo \"Expected file do not exist\"\n            exit 1\n          fi\n          if [ \"$(cat $gzipFile)\" != \"This is a going to be a test for a large enough file that should get compressed with GZip. The @actions/artifact package uses GZip to upload files. This text should have a compression ratio greater than 100% so it should get uploaded using GZip\" ] ; then\n            echo \"File contents of downloaded artifact is incorrect\"\n            exit 1\n          fi\n      \n      - name: 'Download artifact #4'\n        uses: actions/download-artifact@v2\n        with:\n          name: 'Multi-Path-Artifact'\n          path: multi/artifact\n      \n      - name: 'Verify Artifact #4'\n        run: |\n          file1=\"multi/artifact/dir-1/file1.txt\"\n          file2=\"multi/artifact/dir-2/file2.txt\"\n          if [ ! -f $file1 -o ! -f $file2 ] ; then\n            echo \"Expected files do not exist\"\n            exit 1\n          fi\n          if [ \"$(cat $file1)\" != \"Lorem ipsum dolor sit amet\" -o \"$(cat $file2)\" != \"Hello world from file #2\" ] ; then\n            echo \"File contents of downloaded artifacts are incorrect\"\n            exit 1\n          fi\n      \n      - name: 'Download artifact #5'\n        uses: actions/download-artifact@v2\n        with:\n          name: 'Mid-Size-Artifact'\n          path: mid-size/artifact/path\n      \n      - name: 'Verify Artifact #5'\n        run: |\n          file=\"mid-size/artifact/path/file5.rnd\"\n          if [ ! -f $file ] ; then\n            echo \"Expected file does not exist\"\n            exit 1\n          fi\n          if ! diff $file path/to/dir-5/file5.rnd ; then\n            echo \"File contents of downloaded artifact are incorrect\"\n            exit 1\n          fi\n      \n      - name: 'Download artifact #6'\n        uses: actions/download-artifact@v2\n        with:\n          name: 'Big-Artifact'\n          path: big/artifact/path\n      \n      - name: 'Verify Artifact #6'\n        run: |\n          file=\"big/artifact/path/file6.rnd\"\n          if [ ! -f $file ] ; then\n            echo \"Expected file does not exist\"\n            exit 1\n          fi\n          if ! diff $file path/to/dir-6/file6.rnd ; then\n            echo \"File contents of downloaded artifact are incorrect\"\n            exit 1\n          fi\n\n      - name: 'Download artifact #7'\n        uses: actions/download-artifact@v2\n        with:\n          name: 'Big-Uploaded-Twice'\n          path: big-uploaded-twice/artifact/path\n\n      - name: 'Verify Artifact #7'\n        run: |\n          file=\"big-uploaded-twice/artifact/path/file7.rnd\"\n          if [ ! -f $file ] ; then\n            echo \"Expected file does not exist\"\n            exit 1\n          fi\n          if ! diff $file path/to/dir-7/file7.rnd ; then\n            echo \"File contents of downloaded artifact are incorrect\"\n            exit 1\n          fi\n"
  },
  {
    "path": "pkg/artifacts/testdata/v4/artifacts.yml",
    "content": "on:\n  push:\njobs:\n  _5:\n    runs-on: ubuntu-latest\n    steps: \n    - run: env\n    - run: |\n        github:\n        ${{ tojson(github) }}\n        inputs:\n        ${{ tojson(inputs) }}\n        matrix:\n        ${{ tojson(matrix) }}\n        needs:\n        ${{ tojson(needs) }}\n        strategy:\n        ${{ tojson(strategy) }}            \n      shell: cp {0} context.txt\n    - run: echo Artifact2 > data.txt\n\n    - uses: actions/upload-artifact@v4\n      with:\n        name: test\n        path: context.txt\n\n    - uses: actions/upload-artifact@v4\n      with:\n        name: test2\n        path: data.txt\n\n    - uses: actions/download-artifact@v4\n      with:\n        name: test\n        path: out\n    - run: cat out/context.txt\n\n    - name: assert\n      run: |\n        [[ \"$(cat context.txt)\" = \"$(cat out/context.txt)\" ]] || exit 1\n      shell: bash\n\n    - run: |\n        No content        \n      shell: cp {0} context.txt\n    - uses: actions/upload-artifact@v4\n      with:\n        name: test\n        path: context.txt\n        overwrite: true\n  \n    - uses: actions/download-artifact@v4\n      with:\n        name: test\n        path: out2\n    - run: cat out2/context.txt\n\n    - name: assert 2\n      run: |\n        [[ \"$(cat context.txt)\" = \"$(cat out2/context.txt)\" ]] || exit 1\n      shell: bash\n\n    - uses: actions/download-artifact@v4\n      with:\n        name: test2\n        path: out3\n    - run: cat out3/data.txt\n\n    - name: assert 3\n      run: |\n        [[ \"$(cat data.txt)\" = \"$(cat out3/data.txt)\" ]] || exit 1\n      shell: bash\n\n    - uses: actions/download-artifact@v4\n      with:\n        pattern: \"test*\"\n        path: out4\n        merge-multiple: true\n\n    - run: cat out4/data.txt\n    - run: cat out4/context.txt\n\n    - name: assert 4\n      run: |\n        [[ \"$(cat context.txt)\" = \"$(cat out4/context.txt)\" ]] || exit 1\n        [[ \"$(cat data.txt)\" = \"$(cat out4/data.txt)\" ]] || exit 1\n      shell: bash\n"
  },
  {
    "path": "pkg/common/auth.go",
    "content": "// Copyright 2024 The Gitea Authors. All rights reserved.\n// SPDX-License-Identifier: MIT\n\npackage common\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/golang-jwt/jwt/v5\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype actionsClaims struct {\n\tjwt.RegisteredClaims\n\tScp    string `json:\"scp\"`\n\tTaskID int64\n\tRunID  int64\n\tJobID  int64\n\tAc     string `json:\"ac\"`\n}\n\ntype actionsCacheScope struct {\n\tScope      string\n\tPermission actionsCachePermission\n}\n\ntype actionsCachePermission int\n\nconst (\n\tactionsCachePermissionRead = 1 << iota\n\tactionsCachePermissionWrite\n)\n\nfunc CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) {\n\tnow := time.Now()\n\n\tac, err := json.Marshal(&[]actionsCacheScope{\n\t\t{\n\t\t\tScope:      \"\",\n\t\t\tPermission: actionsCachePermissionWrite,\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tclaims := actionsClaims{\n\t\tRegisteredClaims: jwt.RegisteredClaims{\n\t\t\tExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)),\n\t\t\tNotBefore: jwt.NewNumericDate(now),\n\t\t},\n\t\tScp:    fmt.Sprintf(\"Actions.Results:%d:%d\", runID, jobID),\n\t\tTaskID: taskID,\n\t\tRunID:  runID,\n\t\tJobID:  jobID,\n\t\tAc:     string(ac),\n\t}\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\n\ttokenString, err := token.SignedString([]byte{})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn tokenString, nil\n}\n\nfunc ParseAuthorizationToken(req *http.Request) (int64, error) {\n\th := req.Header.Get(\"Authorization\")\n\tif h == \"\" {\n\t\treturn 0, nil\n\t}\n\n\tparts := strings.SplitN(h, \" \", 2)\n\tif len(parts) != 2 {\n\t\tlog.Errorf(\"split token failed: %s\", h)\n\t\treturn 0, fmt.Errorf(\"split token failed\")\n\t}\n\n\ttoken, err := jwt.ParseWithClaims(parts[1], &actionsClaims{}, func(t *jwt.Token) (any, error) {\n\t\tif _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected signing method: %v\", t.Header[\"alg\"])\n\t\t}\n\t\treturn []byte{}, nil\n\t})\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tc, ok := token.Claims.(*actionsClaims)\n\tif !token.Valid || !ok {\n\t\treturn 0, fmt.Errorf(\"invalid token claim\")\n\t}\n\n\treturn c.TaskID, nil\n}\n"
  },
  {
    "path": "pkg/common/auth_test.go",
    "content": "// Copyright 2024 The Gitea Authors. All rights reserved.\n// SPDX-License-Identifier: MIT\n\npackage common\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"testing\"\n\n\t\"github.com/golang-jwt/jwt/v5\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCreateAuthorizationToken(t *testing.T) {\n\tvar taskID int64 = 23\n\ttoken, err := CreateAuthorizationToken(taskID, 1, 2)\n\tassert.Nil(t, err)\n\tassert.NotEqual(t, \"\", token)\n\tclaims := jwt.MapClaims{}\n\t_, err = jwt.ParseWithClaims(token, claims, func(_ *jwt.Token) (interface{}, error) {\n\t\treturn []byte{}, nil\n\t})\n\tassert.Nil(t, err)\n\tscp, ok := claims[\"scp\"]\n\tassert.True(t, ok, \"Has scp claim in jwt token\")\n\tassert.Contains(t, scp, \"Actions.Results:1:2\")\n\ttaskIDClaim, ok := claims[\"TaskID\"]\n\tassert.True(t, ok, \"Has TaskID claim in jwt token\")\n\tassert.Equal(t, float64(taskID), taskIDClaim, \"Supplied taskid must match stored one\")\n\tacClaim, ok := claims[\"ac\"]\n\tassert.True(t, ok, \"Has ac claim in jwt token\")\n\tac, ok := acClaim.(string)\n\tassert.True(t, ok, \"ac claim is a string for buildx gha cache\")\n\tscopes := []actionsCacheScope{}\n\terr = json.Unmarshal([]byte(ac), &scopes)\n\tassert.NoError(t, err, \"ac claim is a json list for buildx gha cache\")\n\tassert.GreaterOrEqual(t, len(scopes), 1, \"Expected at least one action cache scope for buildx gha cache\")\n}\n\nfunc TestParseAuthorizationToken(t *testing.T) {\n\tvar taskID int64 = 23\n\ttoken, err := CreateAuthorizationToken(taskID, 1, 2)\n\tassert.Nil(t, err)\n\tassert.NotEqual(t, \"\", token)\n\theaders := http.Header{}\n\theaders.Set(\"Authorization\", \"Bearer \"+token)\n\trTaskID, err := ParseAuthorizationToken(&http.Request{\n\t\tHeader: headers,\n\t})\n\tassert.Nil(t, err)\n\tassert.Equal(t, taskID, rTaskID)\n}\n\nfunc TestParseAuthorizationTokenNoAuthHeader(t *testing.T) {\n\theaders := http.Header{}\n\trTaskID, err := ParseAuthorizationToken(&http.Request{\n\t\tHeader: headers,\n\t})\n\tassert.Nil(t, err)\n\tassert.Equal(t, int64(0), rTaskID)\n}\n"
  },
  {
    "path": "pkg/common/cartesian.go",
    "content": "package common\n\n// CartesianProduct takes map of lists and returns list of unique tuples\nfunc CartesianProduct(mapOfLists map[string][]interface{}) []map[string]interface{} {\n\tlistNames := make([]string, 0)\n\tlists := make([][]interface{}, 0)\n\tfor k, v := range mapOfLists {\n\t\tlistNames = append(listNames, k)\n\t\tlists = append(lists, v)\n\t}\n\n\tlistCart := cartN(lists...)\n\n\trtn := make([]map[string]interface{}, 0)\n\tfor _, list := range listCart {\n\t\tvMap := make(map[string]interface{})\n\t\tfor i, v := range list {\n\t\t\tvMap[listNames[i]] = v\n\t\t}\n\t\trtn = append(rtn, vMap)\n\t}\n\treturn rtn\n}\n\nfunc cartN(a ...[]interface{}) [][]interface{} {\n\tc := 1\n\tfor _, a := range a {\n\t\tc *= len(a)\n\t}\n\tif c == 0 || len(a) == 0 {\n\t\treturn nil\n\t}\n\tp := make([][]interface{}, c)\n\tb := make([]interface{}, c*len(a))\n\tn := make([]int, len(a))\n\ts := 0\n\tfor i := range p {\n\t\te := s + len(a)\n\t\tpi := b[s:e]\n\t\tp[i] = pi\n\t\ts = e\n\t\tfor j, n := range n {\n\t\t\tpi[j] = a[j][n]\n\t\t}\n\t\tfor j := len(n) - 1; j >= 0; j-- {\n\t\t\tn[j]++\n\t\t\tif n[j] < len(a[j]) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tn[j] = 0\n\t\t}\n\t}\n\treturn p\n}\n"
  },
  {
    "path": "pkg/common/cartesian_test.go",
    "content": "package common\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCartesianProduct(t *testing.T) {\n\tassert := assert.New(t)\n\tinput := map[string][]interface{}{\n\t\t\"foo\": {1, 2, 3, 4},\n\t\t\"bar\": {\"a\", \"b\", \"c\"},\n\t\t\"baz\": {false, true},\n\t}\n\n\toutput := CartesianProduct(input)\n\tassert.Len(output, 24)\n\n\tfor _, v := range output {\n\t\tassert.Len(v, 3)\n\n\t\tassert.Contains(v, \"foo\")\n\t\tassert.Contains(v, \"bar\")\n\t\tassert.Contains(v, \"baz\")\n\t}\n\n\tinput = map[string][]interface{}{\n\t\t\"foo\": {1, 2, 3, 4},\n\t\t\"bar\": {},\n\t\t\"baz\": {false, true},\n\t}\n\toutput = CartesianProduct(input)\n\tassert.Len(output, 0)\n\n\tinput = map[string][]interface{}{}\n\toutput = CartesianProduct(input)\n\tassert.Len(output, 0)\n}\n"
  },
  {
    "path": "pkg/common/context.go",
    "content": "package common\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n)\n\nfunc createGracefulJobCancellationContext() (context.Context, func(), chan os.Signal) {\n\tctx := context.Background()\n\tctx, forceCancel := context.WithCancel(ctx)\n\tcancelCtx, cancel := context.WithCancel(ctx)\n\tctx = WithJobCancelContext(ctx, cancelCtx)\n\n\t// trap Ctrl+C and call cancel on the context\n\tc := make(chan os.Signal, 1)\n\tsignal.Notify(c, os.Interrupt, syscall.SIGTERM)\n\tgo func() {\n\t\tselect {\n\t\tcase sig := <-c:\n\t\t\tif sig == os.Interrupt {\n\t\t\t\tcancel()\n\t\t\t\tselect {\n\t\t\t\tcase <-c:\n\t\t\t\t\tforceCancel()\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tforceCancel()\n\t\t\t}\n\t\tcase <-ctx.Done():\n\t\t}\n\t}()\n\treturn ctx, func() {\n\t\tsignal.Stop(c)\n\t\tforceCancel()\n\t\tcancel()\n\t}, c\n}\n\nfunc CreateGracefulJobCancellationContext() (context.Context, func()) {\n\tctx, cancel, _ := createGracefulJobCancellationContext()\n\treturn ctx, cancel\n}\n"
  },
  {
    "path": "pkg/common/context_test.go",
    "content": "package common\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"syscall\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestGracefulJobCancellationViaSigint(t *testing.T) {\n\tctx, cancel, channel := createGracefulJobCancellationContext()\n\tdefer cancel()\n\tassert.NotNil(t, ctx)\n\tassert.NotNil(t, cancel)\n\tassert.NotNil(t, channel)\n\tcancelCtx := JobCancelContext(ctx)\n\tassert.NotNil(t, cancelCtx)\n\tassert.NoError(t, ctx.Err())\n\tassert.NoError(t, cancelCtx.Err())\n\tchannel <- os.Interrupt\n\tselect {\n\tcase <-time.After(1 * time.Second):\n\t\tt.Fatal(\"context not canceled\")\n\tcase <-cancelCtx.Done():\n\tcase <-ctx.Done():\n\t}\n\tif assert.Error(t, cancelCtx.Err(), \"context canceled\") {\n\t\tassert.Equal(t, context.Canceled, cancelCtx.Err())\n\t}\n\tassert.NoError(t, ctx.Err())\n\tchannel <- os.Interrupt\n\tselect {\n\tcase <-time.After(1 * time.Second):\n\t\tt.Fatal(\"context not canceled\")\n\tcase <-ctx.Done():\n\t}\n\tif assert.Error(t, ctx.Err(), \"context canceled\") {\n\t\tassert.Equal(t, context.Canceled, ctx.Err())\n\t}\n}\n\nfunc TestForceCancellationViaSigterm(t *testing.T) {\n\tctx, cancel, channel := createGracefulJobCancellationContext()\n\tdefer cancel()\n\tassert.NotNil(t, ctx)\n\tassert.NotNil(t, cancel)\n\tassert.NotNil(t, channel)\n\tcancelCtx := JobCancelContext(ctx)\n\tassert.NotNil(t, cancelCtx)\n\tassert.NoError(t, ctx.Err())\n\tassert.NoError(t, cancelCtx.Err())\n\tchannel <- syscall.SIGTERM\n\tselect {\n\tcase <-time.After(1 * time.Second):\n\t\tt.Fatal(\"context not canceled\")\n\tcase <-cancelCtx.Done():\n\t}\n\tselect {\n\tcase <-time.After(1 * time.Second):\n\t\tt.Fatal(\"context not canceled\")\n\tcase <-ctx.Done():\n\t}\n\tif assert.Error(t, ctx.Err(), \"context canceled\") {\n\t\tassert.Equal(t, context.Canceled, ctx.Err())\n\t}\n\tif assert.Error(t, cancelCtx.Err(), \"context canceled\") {\n\t\tassert.Equal(t, context.Canceled, cancelCtx.Err())\n\t}\n}\n\nfunc TestCreateGracefulJobCancellationContext(t *testing.T) {\n\tctx, cancel := CreateGracefulJobCancellationContext()\n\tdefer cancel()\n\tassert.NotNil(t, ctx)\n\tassert.NotNil(t, cancel)\n\tcancelCtx := JobCancelContext(ctx)\n\tassert.NotNil(t, cancelCtx)\n\tassert.NoError(t, cancelCtx.Err())\n}\n\nfunc TestCreateGracefulJobCancellationContextCancelFunc(t *testing.T) {\n\tctx, cancel := CreateGracefulJobCancellationContext()\n\tassert.NotNil(t, ctx)\n\tassert.NotNil(t, cancel)\n\tcancelCtx := JobCancelContext(ctx)\n\tassert.NotNil(t, cancelCtx)\n\tassert.NoError(t, cancelCtx.Err())\n\tcancel()\n\tif assert.Error(t, ctx.Err(), \"context canceled\") {\n\t\tassert.Equal(t, context.Canceled, ctx.Err())\n\t}\n\tif assert.Error(t, cancelCtx.Err(), \"context canceled\") {\n\t\tassert.Equal(t, context.Canceled, cancelCtx.Err())\n\t}\n}\n"
  },
  {
    "path": "pkg/common/draw.go",
    "content": "package common\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\n// Style is a specific style\ntype Style int\n\n// Styles\nconst (\n\tStyleDoubleLine = iota\n\tStyleSingleLine\n\tStyleDashedLine\n\tStyleNoLine\n)\n\n// NewPen creates a new pen\nfunc NewPen(style Style, color int) *Pen {\n\tbgcolor := 49\n\tif os.Getenv(\"CLICOLOR\") == \"0\" {\n\t\tcolor = 0\n\t\tbgcolor = 0\n\t}\n\treturn &Pen{\n\t\tstyle:   style,\n\t\tcolor:   color,\n\t\tbgcolor: bgcolor,\n\t}\n}\n\ntype styleDef struct {\n\tcornerTL string\n\tcornerTR string\n\tcornerBL string\n\tcornerBR string\n\tlineH    string\n\tlineV    string\n}\n\nvar styleDefs = []styleDef{\n\t{\"\\u2554\", \"\\u2557\", \"\\u255a\", \"\\u255d\", \"\\u2550\", \"\\u2551\"},\n\t{\"\\u256d\", \"\\u256e\", \"\\u2570\", \"\\u256f\", \"\\u2500\", \"\\u2502\"},\n\t{\"\\u250c\", \"\\u2510\", \"\\u2514\", \"\\u2518\", \"\\u254c\", \"\\u254e\"},\n\t{\" \", \" \", \" \", \" \", \" \", \" \"},\n}\n\n// Pen struct\ntype Pen struct {\n\tstyle   Style\n\tcolor   int\n\tbgcolor int\n}\n\n// Drawing struct\ntype Drawing struct {\n\tbuf   *strings.Builder\n\twidth int\n}\n\nfunc (p *Pen) drawTopBars(buf io.Writer, labels ...string) {\n\tstyle := styleDefs[p.style]\n\tfor _, label := range labels {\n\t\tbar := strings.Repeat(style.lineH, len(label)+2)\n\t\tfmt.Fprintf(buf, \" \")\n\t\tfmt.Fprintf(buf, \"\\x1b[%d;%dm\", p.color, p.bgcolor)\n\t\tfmt.Fprintf(buf, \"%s%s%s\", style.cornerTL, bar, style.cornerTR)\n\t\tfmt.Fprintf(buf, \"\\x1b[%dm\", 0)\n\t}\n\tfmt.Fprintf(buf, \"\\n\")\n}\nfunc (p *Pen) drawBottomBars(buf io.Writer, labels ...string) {\n\tstyle := styleDefs[p.style]\n\tfor _, label := range labels {\n\t\tbar := strings.Repeat(style.lineH, len(label)+2)\n\t\tfmt.Fprintf(buf, \" \")\n\t\tfmt.Fprintf(buf, \"\\x1b[%d;%dm\", p.color, p.bgcolor)\n\t\tfmt.Fprintf(buf, \"%s%s%s\", style.cornerBL, bar, style.cornerBR)\n\t\tfmt.Fprintf(buf, \"\\x1b[%dm\", 0)\n\t}\n\tfmt.Fprintf(buf, \"\\n\")\n}\nfunc (p *Pen) drawLabels(buf io.Writer, labels ...string) {\n\tstyle := styleDefs[p.style]\n\tfor _, label := range labels {\n\t\tfmt.Fprintf(buf, \" \")\n\t\tfmt.Fprintf(buf, \"\\x1b[%d;%dm\", p.color, p.bgcolor)\n\t\tfmt.Fprintf(buf, \"%s %s %s\", style.lineV, label, style.lineV)\n\t\tfmt.Fprintf(buf, \"\\x1b[%dm\", 0)\n\t}\n\tfmt.Fprintf(buf, \"\\n\")\n}\n\n// DrawArrow between boxes\nfunc (p *Pen) DrawArrow() *Drawing {\n\tdrawing := &Drawing{\n\t\tbuf:   new(strings.Builder),\n\t\twidth: 1,\n\t}\n\tfmt.Fprintf(drawing.buf, \"\\x1b[%dm\", p.color)\n\tfmt.Fprintf(drawing.buf, \"\\u2b07\")\n\tfmt.Fprintf(drawing.buf, \"\\x1b[%dm\", 0)\n\treturn drawing\n}\n\n// DrawBoxes to draw boxes\nfunc (p *Pen) DrawBoxes(labels ...string) *Drawing {\n\twidth := 0\n\tfor _, l := range labels {\n\t\twidth += len(l) + 2 + 2 + 1\n\t}\n\tdrawing := &Drawing{\n\t\tbuf:   new(strings.Builder),\n\t\twidth: width,\n\t}\n\tp.drawTopBars(drawing.buf, labels...)\n\tp.drawLabels(drawing.buf, labels...)\n\tp.drawBottomBars(drawing.buf, labels...)\n\n\treturn drawing\n}\n\n// Draw to writer\nfunc (d *Drawing) Draw(writer io.Writer, centerOnWidth int) {\n\tpadSize := (centerOnWidth - d.GetWidth()) / 2\n\tif padSize < 0 {\n\t\tpadSize = 0\n\t}\n\tfor _, l := range strings.Split(d.buf.String(), \"\\n\") {\n\t\tif len(l) > 0 {\n\t\t\tpadding := strings.Repeat(\" \", padSize)\n\t\t\tfmt.Fprintf(writer, \"%s%s\\n\", padding, l)\n\t\t}\n\t}\n}\n\n// GetWidth of drawing\nfunc (d *Drawing) GetWidth() int {\n\treturn d.width\n}\n"
  },
  {
    "path": "pkg/common/dryrun.go",
    "content": "package common\n\nimport (\n\t\"context\"\n)\n\ntype dryrunContextKey string\n\nconst dryrunContextKeyVal = dryrunContextKey(\"dryrun\")\n\n// Dryrun returns true if the current context is dryrun\nfunc Dryrun(ctx context.Context) bool {\n\tval := ctx.Value(dryrunContextKeyVal)\n\tif val != nil {\n\t\tif dryrun, ok := val.(bool); ok {\n\t\t\treturn dryrun\n\t\t}\n\t}\n\treturn false\n}\n\n// WithDryrun adds a value to the context for dryrun\nfunc WithDryrun(ctx context.Context, dryrun bool) context.Context {\n\treturn context.WithValue(ctx, dryrunContextKeyVal, dryrun)\n}\n"
  },
  {
    "path": "pkg/common/executor.go",
    "content": "package common\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// Warning that implements `error` but safe to ignore\ntype Warning struct {\n\tMessage string\n}\n\n// Error the contract for error\nfunc (w Warning) Error() string {\n\treturn w.Message\n}\n\n// Warningf create a warning\nfunc Warningf(format string, args ...interface{}) Warning {\n\tw := Warning{\n\t\tMessage: fmt.Sprintf(format, args...),\n\t}\n\treturn w\n}\n\n// Executor define contract for the steps of a workflow\ntype Executor func(ctx context.Context) error\n\n// Conditional define contract for the conditional predicate\ntype Conditional func(ctx context.Context) bool\n\n// NewInfoExecutor is an executor that logs messages\nfunc NewInfoExecutor(format string, args ...interface{}) Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := Logger(ctx)\n\t\tlogger.Infof(format, args...)\n\t\treturn nil\n\t}\n}\n\n// NewDebugExecutor is an executor that logs messages\nfunc NewDebugExecutor(format string, args ...interface{}) Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := Logger(ctx)\n\t\tlogger.Debugf(format, args...)\n\t\treturn nil\n\t}\n}\n\n// NewPipelineExecutor creates a new executor from a series of other executors\nfunc NewPipelineExecutor(executors ...Executor) Executor {\n\tif len(executors) == 0 {\n\t\treturn func(_ context.Context) error {\n\t\t\treturn nil\n\t\t}\n\t}\n\tvar rtn Executor\n\tfor _, executor := range executors {\n\t\tif rtn == nil {\n\t\t\trtn = executor\n\t\t} else {\n\t\t\trtn = rtn.Then(executor)\n\t\t}\n\t}\n\treturn rtn\n}\n\n// NewConditionalExecutor creates a new executor based on conditions\nfunc NewConditionalExecutor(conditional Conditional, trueExecutor Executor, falseExecutor Executor) Executor {\n\treturn func(ctx context.Context) error {\n\t\tif conditional(ctx) {\n\t\t\tif trueExecutor != nil {\n\t\t\t\treturn trueExecutor(ctx)\n\t\t\t}\n\t\t} else {\n\t\t\tif falseExecutor != nil {\n\t\t\t\treturn falseExecutor(ctx)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// NewErrorExecutor creates a new executor that always errors out\nfunc NewErrorExecutor(err error) Executor {\n\treturn func(_ context.Context) error {\n\t\treturn err\n\t}\n}\n\n// NewParallelExecutor creates a new executor from a parallel of other executors\nfunc NewParallelExecutor(parallel int, executors ...Executor) Executor {\n\treturn func(ctx context.Context) error {\n\t\twork := make(chan Executor, len(executors))\n\t\terrs := make(chan error, len(executors))\n\n\t\tif 1 > parallel {\n\t\t\tlog.Debugf(\"Parallel tasks (%d) below minimum, setting to 1\", parallel)\n\t\t\tparallel = 1\n\t\t}\n\n\t\tfor i := 0; i < parallel; i++ {\n\t\t\tgo func(work <-chan Executor, errs chan<- error) {\n\t\t\t\tfor executor := range work {\n\t\t\t\t\terrs <- executor(ctx)\n\t\t\t\t}\n\t\t\t}(work, errs)\n\t\t}\n\n\t\tfor i := 0; i < len(executors); i++ {\n\t\t\twork <- executors[i]\n\t\t}\n\t\tclose(work)\n\n\t\t// Executor waits all executors to cleanup these resources.\n\t\tvar firstErr error\n\t\tfor i := 0; i < len(executors); i++ {\n\t\t\terr := <-errs\n\t\t\tif firstErr == nil {\n\t\t\t\tfirstErr = err\n\t\t\t}\n\t\t}\n\n\t\tif err := ctx.Err(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn firstErr\n\t}\n}\n\nfunc NewFieldExecutor(name string, value interface{}, exec Executor) Executor {\n\treturn func(ctx context.Context) error {\n\t\treturn exec(WithLogger(ctx, Logger(ctx).WithField(name, value)))\n\t}\n}\n\n// Then runs another executor if this executor succeeds\nfunc (e Executor) ThenError(then func(ctx context.Context, err error) error) Executor {\n\treturn func(ctx context.Context) error {\n\t\terr := e(ctx)\n\t\tif err != nil {\n\t\t\tswitch err.(type) {\n\t\t\tcase Warning:\n\t\t\t\tLogger(ctx).Warning(err.Error())\n\t\t\tdefault:\n\t\t\t\treturn then(ctx, err)\n\t\t\t}\n\t\t}\n\t\tif ctx.Err() != nil {\n\t\t\treturn ctx.Err()\n\t\t}\n\t\treturn then(ctx, err)\n\t}\n}\n\n// Then runs another executor if this executor succeeds\nfunc (e Executor) Then(then Executor) Executor {\n\treturn func(ctx context.Context) error {\n\t\terr := e(ctx)\n\t\tif err != nil {\n\t\t\tswitch err.(type) {\n\t\t\tcase Warning:\n\t\t\t\tLogger(ctx).Warning(err.Error())\n\t\t\tdefault:\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif ctx.Err() != nil {\n\t\t\treturn ctx.Err()\n\t\t}\n\t\treturn then(ctx)\n\t}\n}\n\n// Then runs another executor if this executor succeeds\nfunc (e Executor) OnError(then Executor) Executor {\n\treturn func(ctx context.Context) error {\n\t\terr := e(ctx)\n\t\tif err != nil {\n\t\t\tswitch err.(type) {\n\t\t\tcase Warning:\n\t\t\t\tLogger(ctx).Warning(err.Error())\n\t\t\tdefault:\n\t\t\t\treturn errors.Join(err, then(ctx))\n\t\t\t}\n\t\t}\n\t\tif ctx.Err() != nil {\n\t\t\treturn ctx.Err()\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// If only runs this executor if conditional is true\nfunc (e Executor) If(conditional Conditional) Executor {\n\treturn func(ctx context.Context) error {\n\t\tif conditional(ctx) {\n\t\t\treturn e(ctx)\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// IfNot only runs this executor if conditional is true\nfunc (e Executor) IfNot(conditional Conditional) Executor {\n\treturn func(ctx context.Context) error {\n\t\tif !conditional(ctx) {\n\t\t\treturn e(ctx)\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// IfBool only runs this executor if conditional is true\nfunc (e Executor) IfBool(conditional bool) Executor {\n\treturn e.If(func(_ context.Context) bool {\n\t\treturn conditional\n\t})\n}\n\n// Finally adds an executor to run after other executor\nfunc (e Executor) Finally(finally Executor) Executor {\n\treturn func(ctx context.Context) error {\n\t\terr := e(ctx)\n\t\terr2 := finally(ctx)\n\t\tif err2 != nil {\n\t\t\treturn fmt.Errorf(\"Error occurred running finally: %v (original error: %v)\", err2, err)\n\t\t}\n\t\treturn err\n\t}\n}\n\n// Not return an inverted conditional\nfunc (c Conditional) Not() Conditional {\n\treturn func(ctx context.Context) bool {\n\t\treturn !c(ctx)\n\t}\n}\n"
  },
  {
    "path": "pkg/common/executor_test.go",
    "content": "package common\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestNewWorkflow(t *testing.T) {\n\tassert := assert.New(t)\n\n\tctx := context.Background()\n\n\t// empty\n\temptyWorkflow := NewPipelineExecutor()\n\tassert.Nil(emptyWorkflow(ctx))\n\n\t// error case\n\terrorWorkflow := NewErrorExecutor(fmt.Errorf(\"test error\"))\n\tassert.NotNil(errorWorkflow(ctx))\n\n\t// multiple success case\n\truncount := 0\n\tsuccessWorkflow := NewPipelineExecutor(\n\t\tfunc(_ context.Context) error {\n\t\t\truncount++\n\t\t\treturn nil\n\t\t},\n\t\tfunc(_ context.Context) error {\n\t\t\truncount++\n\t\t\treturn nil\n\t\t})\n\tassert.Nil(successWorkflow(ctx))\n\tassert.Equal(2, runcount)\n}\n\nfunc TestNewConditionalExecutor(t *testing.T) {\n\tassert := assert.New(t)\n\n\tctx := context.Background()\n\n\ttrueCount := 0\n\tfalseCount := 0\n\n\terr := NewConditionalExecutor(func(_ context.Context) bool {\n\t\treturn false\n\t}, func(_ context.Context) error {\n\t\ttrueCount++\n\t\treturn nil\n\t}, func(_ context.Context) error {\n\t\tfalseCount++\n\t\treturn nil\n\t})(ctx)\n\n\tassert.Nil(err)\n\tassert.Equal(0, trueCount)\n\tassert.Equal(1, falseCount)\n\n\terr = NewConditionalExecutor(func(_ context.Context) bool {\n\t\treturn true\n\t}, func(_ context.Context) error {\n\t\ttrueCount++\n\t\treturn nil\n\t}, func(_ context.Context) error {\n\t\tfalseCount++\n\t\treturn nil\n\t})(ctx)\n\n\tassert.Nil(err)\n\tassert.Equal(1, trueCount)\n\tassert.Equal(1, falseCount)\n}\n\nfunc TestNewParallelExecutor(t *testing.T) {\n\tassert := assert.New(t)\n\n\tctx := context.Background()\n\n\tcount := 0\n\tactiveCount := 0\n\tmaxCount := 0\n\temptyWorkflow := NewPipelineExecutor(func(_ context.Context) error {\n\t\tcount++\n\n\t\tactiveCount++\n\t\tif activeCount > maxCount {\n\t\t\tmaxCount = activeCount\n\t\t}\n\t\ttime.Sleep(2 * time.Second)\n\t\tactiveCount--\n\n\t\treturn nil\n\t})\n\n\terr := NewParallelExecutor(2, emptyWorkflow, emptyWorkflow, emptyWorkflow)(ctx)\n\n\tassert.Equal(3, count, \"should run all 3 executors\")\n\tassert.Equal(2, maxCount, \"should run at most 2 executors in parallel\")\n\tassert.Nil(err)\n\n\t// Reset to test running the executor with 0 parallelism\n\tcount = 0\n\tactiveCount = 0\n\tmaxCount = 0\n\n\terrSingle := NewParallelExecutor(0, emptyWorkflow, emptyWorkflow, emptyWorkflow)(ctx)\n\n\tassert.Equal(3, count, \"should run all 3 executors\")\n\tassert.Equal(1, maxCount, \"should run at most 1 executors in parallel\")\n\tassert.Nil(errSingle)\n}\n\nfunc TestNewParallelExecutorFailed(t *testing.T) {\n\tassert := assert.New(t)\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tcancel()\n\n\tcount := 0\n\terrorWorkflow := NewPipelineExecutor(func(_ context.Context) error {\n\t\tcount++\n\t\treturn fmt.Errorf(\"fake error\")\n\t})\n\terr := NewParallelExecutor(1, errorWorkflow)(ctx)\n\tassert.Equal(1, count)\n\tassert.ErrorIs(context.Canceled, err)\n}\n\nfunc TestNewParallelExecutorCanceled(t *testing.T) {\n\tassert := assert.New(t)\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tcancel()\n\n\terrExpected := fmt.Errorf(\"fake error\")\n\n\tcount := 0\n\tsuccessWorkflow := NewPipelineExecutor(func(_ context.Context) error {\n\t\tcount++\n\t\treturn nil\n\t})\n\terrorWorkflow := NewPipelineExecutor(func(_ context.Context) error {\n\t\tcount++\n\t\treturn errExpected\n\t})\n\terr := NewParallelExecutor(3, errorWorkflow, successWorkflow, successWorkflow)(ctx)\n\tassert.Equal(3, count)\n\tassert.Error(errExpected, err)\n}\n"
  },
  {
    "path": "pkg/common/file.go",
    "content": "package common\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\n// CopyFile copy file\nfunc CopyFile(source string, dest string) (err error) {\n\tsourcefile, err := os.Open(source)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer sourcefile.Close()\n\n\tdestfile, err := os.Create(dest)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer destfile.Close()\n\n\t_, err = io.Copy(destfile, sourcefile)\n\tif err == nil {\n\t\tsourceinfo, err := os.Stat(source)\n\t\tif err != nil {\n\t\t\t_ = os.Chmod(dest, sourceinfo.Mode())\n\t\t}\n\t}\n\n\treturn\n}\n\n// CopyDir recursive copy of directory\nfunc CopyDir(source string, dest string) (err error) {\n\t// get properties of source dir\n\tsourceinfo, err := os.Stat(source)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// create dest dir\n\n\terr = os.MkdirAll(dest, sourceinfo.Mode())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tobjects, err := os.ReadDir(source)\n\n\tfor _, obj := range objects {\n\t\tsourcefilepointer := source + \"/\" + obj.Name()\n\n\t\tdestinationfilepointer := dest + \"/\" + obj.Name()\n\n\t\tif obj.IsDir() {\n\t\t\t// create sub-directories - recursively\n\t\t\terr = CopyDir(sourcefilepointer, destinationfilepointer)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t}\n\t\t} else {\n\t\t\t// perform copy\n\t\t\terr = CopyFile(sourcefilepointer, destinationfilepointer)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t}\n\t\t}\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "pkg/common/git/git.go",
    "content": "package git\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/config\"\n\t\"github.com/go-git/go-git/v5/plumbing\"\n\t\"github.com/go-git/go-git/v5/plumbing/storer\"\n\t\"github.com/go-git/go-git/v5/plumbing/transport/http\"\n\t\"github.com/mattn/go-isatty\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/nektos/act/pkg/common\"\n)\n\nvar (\n\tcodeCommitHTTPRegex = regexp.MustCompile(`^https?://git-codecommit\\.(.+)\\.amazonaws.com/v1/repos/(.+)$`)\n\tcodeCommitSSHRegex  = regexp.MustCompile(`ssh://git-codecommit\\.(.+)\\.amazonaws.com/v1/repos/(.+)$`)\n\tgithubHTTPRegex     = regexp.MustCompile(`^https?://.*github.com.*/(.+)/(.+?)(?:.git)?$`)\n\tgithubSSHRegex      = regexp.MustCompile(`github.com[:/](.+)/(.+?)(?:.git)?$`)\n\n\tcloneLock sync.Mutex\n\n\tErrShortRef = errors.New(\"short SHA references are not supported\")\n\tErrNoRepo   = errors.New(\"unable to find git repo\")\n)\n\ntype Error struct {\n\terr    error\n\tcommit string\n}\n\nfunc (e *Error) Error() string {\n\treturn e.err.Error()\n}\n\nfunc (e *Error) Unwrap() error {\n\treturn e.err\n}\n\nfunc (e *Error) Commit() string {\n\treturn e.commit\n}\n\n// FindGitRevision get the current git revision\nfunc FindGitRevision(ctx context.Context, file string) (shortSha string, sha string, err error) {\n\tlogger := common.Logger(ctx)\n\n\tgitDir, err := git.PlainOpenWithOptions(\n\t\tfile,\n\t\t&git.PlainOpenOptions{\n\t\t\tDetectDotGit:          true,\n\t\t\tEnableDotGitCommonDir: true,\n\t\t},\n\t)\n\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"path\", file, \"not located inside a git repository\")\n\t\treturn \"\", \"\", err\n\t}\n\n\thead, err := gitDir.Reference(plumbing.HEAD, true)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\tif head.Hash().IsZero() {\n\t\treturn \"\", \"\", fmt.Errorf(\"HEAD sha1 could not be resolved\")\n\t}\n\n\thash := head.Hash().String()\n\n\tlogger.Debugf(\"Found revision: %s\", hash)\n\treturn hash[:7], strings.TrimSpace(hash), nil\n}\n\n// FindGitRef get the current git ref\nfunc FindGitRef(ctx context.Context, file string) (string, error) {\n\tlogger := common.Logger(ctx)\n\n\tlogger.Debugf(\"Loading revision from git directory\")\n\t_, ref, err := FindGitRevision(ctx, file)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tlogger.Debugf(\"HEAD points to '%s'\", ref)\n\n\t// Prefer the git library to iterate over the references and find a matching tag or branch.\n\tvar refTag = \"\"\n\tvar refBranch = \"\"\n\trepo, err := git.PlainOpenWithOptions(\n\t\tfile,\n\t\t&git.PlainOpenOptions{\n\t\t\tDetectDotGit:          true,\n\t\t\tEnableDotGitCommonDir: true,\n\t\t},\n\t)\n\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\titer, err := repo.References()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// find the reference that matches the revision's has\n\terr = iter.ForEach(func(r *plumbing.Reference) error {\n\t\t/* tags and branches will have the same hash\n\t\t * when a user checks out a tag, it is not mentioned explicitly\n\t\t * in the go-git package, we must identify the revision\n\t\t * then check if any tag matches that revision,\n\t\t * if so then we checked out a tag\n\t\t * else we look for branches and if matches,\n\t\t * it means we checked out a branch\n\t\t *\n\t\t * If a branches matches first we must continue and check all tags (all references)\n\t\t * in case we match with a tag later in the iteration\n\t\t */\n\t\tif r.Hash().String() == ref {\n\t\t\tif r.Name().IsTag() {\n\t\t\t\trefTag = r.Name().String()\n\t\t\t}\n\t\t\tif r.Name().IsBranch() {\n\t\t\t\trefBranch = r.Name().String()\n\t\t\t}\n\t\t}\n\n\t\t// we found what we where looking for\n\t\tif refTag != \"\" && refBranch != \"\" {\n\t\t\treturn storer.ErrStop\n\t\t}\n\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// order matters here see above comment.\n\tif refTag != \"\" {\n\t\treturn refTag, nil\n\t}\n\tif refBranch != \"\" {\n\t\treturn refBranch, nil\n\t}\n\n\treturn \"\", fmt.Errorf(\"failed to identify reference (tag/branch) for the checked-out revision '%s'\", ref)\n}\n\n// FindGithubRepo get the repo\nfunc FindGithubRepo(ctx context.Context, file, githubInstance, remoteName string) (string, error) {\n\tif remoteName == \"\" {\n\t\tremoteName = \"origin\"\n\t}\n\n\turl, err := findGitRemoteURL(ctx, file, remoteName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\t_, slug, err := findGitSlug(url, githubInstance)\n\treturn slug, err\n}\n\nfunc findGitRemoteURL(_ context.Context, file, remoteName string) (string, error) {\n\trepo, err := git.PlainOpenWithOptions(\n\t\tfile,\n\t\t&git.PlainOpenOptions{\n\t\t\tDetectDotGit:          true,\n\t\t\tEnableDotGitCommonDir: true,\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tremote, err := repo.Remote(remoteName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif len(remote.Config().URLs) < 1 {\n\t\treturn \"\", fmt.Errorf(\"remote '%s' exists but has no URL\", remoteName)\n\t}\n\n\treturn remote.Config().URLs[0], nil\n}\n\nfunc findGitSlug(url string, githubInstance string) (string, string, error) {\n\tif matches := codeCommitHTTPRegex.FindStringSubmatch(url); matches != nil {\n\t\treturn \"CodeCommit\", matches[2], nil\n\t} else if matches := codeCommitSSHRegex.FindStringSubmatch(url); matches != nil {\n\t\treturn \"CodeCommit\", matches[2], nil\n\t} else if matches := githubHTTPRegex.FindStringSubmatch(url); matches != nil {\n\t\treturn \"GitHub\", fmt.Sprintf(\"%s/%s\", matches[1], matches[2]), nil\n\t} else if matches := githubSSHRegex.FindStringSubmatch(url); matches != nil {\n\t\treturn \"GitHub\", fmt.Sprintf(\"%s/%s\", matches[1], matches[2]), nil\n\t} else if githubInstance != \"github.com\" {\n\t\tgheHTTPRegex := regexp.MustCompile(fmt.Sprintf(`^https?://%s/(.+)/(.+?)(?:.git)?$`, githubInstance))\n\t\tgheSSHRegex := regexp.MustCompile(fmt.Sprintf(`%s[:/](.+)/(.+?)(?:.git)?$`, githubInstance))\n\t\tif matches := gheHTTPRegex.FindStringSubmatch(url); matches != nil {\n\t\t\treturn \"GitHubEnterprise\", fmt.Sprintf(\"%s/%s\", matches[1], matches[2]), nil\n\t\t} else if matches := gheSSHRegex.FindStringSubmatch(url); matches != nil {\n\t\t\treturn \"GitHubEnterprise\", fmt.Sprintf(\"%s/%s\", matches[1], matches[2]), nil\n\t\t}\n\t}\n\treturn \"\", url, nil\n}\n\n// NewGitCloneExecutorInput the input for the NewGitCloneExecutor\ntype NewGitCloneExecutorInput struct {\n\tURL         string\n\tRef         string\n\tDir         string\n\tToken       string\n\tOfflineMode bool\n}\n\n// CloneIfRequired ...\nfunc CloneIfRequired(ctx context.Context, refName plumbing.ReferenceName, input NewGitCloneExecutorInput, logger log.FieldLogger) (*git.Repository, error) {\n\t// If the remote URL has changed, remove the directory and clone again.\n\tif r, err := git.PlainOpen(input.Dir); err == nil {\n\t\tif remote, err := r.Remote(\"origin\"); err == nil {\n\t\t\tif len(remote.Config().URLs) > 0 && remote.Config().URLs[0] != input.URL {\n\t\t\t\t_ = os.RemoveAll(input.Dir)\n\t\t\t}\n\t\t}\n\t}\n\n\tr, err := git.PlainOpen(input.Dir)\n\tif err != nil {\n\t\tvar progressWriter io.Writer\n\t\tif isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd()) {\n\t\t\tif entry, ok := logger.(*log.Entry); ok {\n\t\t\t\tprogressWriter = entry.WriterLevel(log.DebugLevel)\n\t\t\t} else if lgr, ok := logger.(*log.Logger); ok {\n\t\t\t\tprogressWriter = lgr.WriterLevel(log.DebugLevel)\n\t\t\t} else {\n\t\t\t\tlog.Errorf(\"Unable to get writer from logger (type=%T)\", logger)\n\t\t\t\tprogressWriter = os.Stdout\n\t\t\t}\n\t\t}\n\n\t\tcloneOptions := git.CloneOptions{\n\t\t\tURL:      input.URL,\n\t\t\tProgress: progressWriter,\n\t\t}\n\t\tif input.Token != \"\" {\n\t\t\tcloneOptions.Auth = &http.BasicAuth{\n\t\t\t\tUsername: \"token\",\n\t\t\t\tPassword: input.Token,\n\t\t\t}\n\t\t}\n\n\t\tr, err = git.PlainCloneContext(ctx, input.Dir, false, &cloneOptions)\n\t\tif err != nil {\n\t\t\tlogger.Errorf(\"Unable to clone %v %s: %v\", input.URL, refName, err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif err = os.Chmod(input.Dir, 0o755); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn r, nil\n}\n\nfunc gitOptions(token string) (fetchOptions git.FetchOptions, pullOptions git.PullOptions) {\n\tfetchOptions.RefSpecs = []config.RefSpec{\"refs/*:refs/*\", \"HEAD:refs/heads/HEAD\"}\n\tpullOptions.Force = true\n\n\tif token != \"\" {\n\t\tauth := &http.BasicAuth{\n\t\t\tUsername: \"token\",\n\t\t\tPassword: token,\n\t\t}\n\t\tfetchOptions.Auth = auth\n\t\tpullOptions.Auth = auth\n\t}\n\n\treturn fetchOptions, pullOptions\n}\n\n// NewGitCloneExecutor creates an executor to clone git repos\n//\n//nolint:gocyclo\nfunc NewGitCloneExecutor(input NewGitCloneExecutorInput) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tlogger.Infof(\"  \\u2601  git clone '%s' # ref=%s\", input.URL, input.Ref)\n\t\tlogger.Debugf(\"  cloning %s to %s\", input.URL, input.Dir)\n\n\t\tcloneLock.Lock()\n\t\tdefer cloneLock.Unlock()\n\n\t\trefName := plumbing.ReferenceName(fmt.Sprintf(\"refs/heads/%s\", input.Ref))\n\t\tr, err := CloneIfRequired(ctx, refName, input, logger)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tisOfflineMode := input.OfflineMode\n\n\t\t// fetch latest changes\n\t\tfetchOptions, pullOptions := gitOptions(input.Token)\n\n\t\tif !isOfflineMode {\n\t\t\terr = r.Fetch(&fetchOptions)\n\t\t\tif err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tvar hash *plumbing.Hash\n\t\trev := plumbing.Revision(input.Ref)\n\t\tif hash, err = r.ResolveRevision(rev); err != nil {\n\t\t\tlogger.Errorf(\"Unable to resolve %s: %v\", input.Ref, err)\n\t\t}\n\n\t\tif hash.String() != input.Ref && len(input.Ref) >= 4 && strings.HasPrefix(hash.String(), input.Ref) {\n\t\t\treturn &Error{\n\t\t\t\terr:    ErrShortRef,\n\t\t\t\tcommit: hash.String(),\n\t\t\t}\n\t\t}\n\n\t\t// At this point we need to know if it's a tag or a branch\n\t\t// And the easiest way to do it is duck typing\n\t\t//\n\t\t// If err is nil, it's a tag so let's proceed with that hash like we would if\n\t\t// it was a sha\n\t\trefType := \"tag\"\n\t\trev = plumbing.Revision(path.Join(\"refs\", \"tags\", input.Ref))\n\t\tif _, err := r.Tag(input.Ref); errors.Is(err, git.ErrTagNotFound) {\n\t\t\trName := plumbing.ReferenceName(path.Join(\"refs\", \"remotes\", \"origin\", input.Ref))\n\t\t\tif _, err := r.Reference(rName, false); errors.Is(err, plumbing.ErrReferenceNotFound) {\n\t\t\t\trefType = \"sha\"\n\t\t\t\trev = plumbing.Revision(input.Ref)\n\t\t\t} else {\n\t\t\t\trefType = \"branch\"\n\t\t\t\trev = plumbing.Revision(rName)\n\t\t\t}\n\t\t}\n\n\t\tif hash, err = r.ResolveRevision(rev); err != nil {\n\t\t\tlogger.Errorf(\"Unable to resolve %s: %v\", input.Ref, err)\n\t\t\treturn err\n\t\t}\n\n\t\tvar w *git.Worktree\n\t\tif w, err = r.Worktree(); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// If the hash resolved doesn't match the ref provided in a workflow then we're\n\t\t// using a branch or tag ref, not a sha\n\t\t//\n\t\t// Repos on disk point to commit hashes, and need to checkout input.Ref before\n\t\t// we try and pull down any changes\n\t\tif hash.String() != input.Ref && refType == \"branch\" {\n\t\t\tlogger.Debugf(\"Provided ref is not a sha. Checking out branch before pulling changes\")\n\t\t\tsourceRef := plumbing.ReferenceName(path.Join(\"refs\", \"remotes\", \"origin\", input.Ref))\n\t\t\tif err = w.Checkout(&git.CheckoutOptions{\n\t\t\t\tBranch: sourceRef,\n\t\t\t\tForce:  true,\n\t\t\t}); err != nil {\n\t\t\t\tlogger.Errorf(\"Unable to checkout %s: %v\", sourceRef, err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif !isOfflineMode {\n\t\t\tif err = w.Pull(&pullOptions); err != nil && err != git.NoErrAlreadyUpToDate {\n\t\t\t\tlogger.Debugf(\"Unable to pull %s: %v\", refName, err)\n\t\t\t}\n\t\t}\n\t\tlogger.Debugf(\"Cloned %s to %s\", input.URL, input.Dir)\n\n\t\tif hash.String() != input.Ref && refType == \"branch\" {\n\t\t\tlogger.Debugf(\"Provided ref is not a sha. Updating branch ref after pull\")\n\t\t\tif hash, err = r.ResolveRevision(rev); err != nil {\n\t\t\t\tlogger.Errorf(\"Unable to resolve %s: %v\", input.Ref, err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err = w.Checkout(&git.CheckoutOptions{\n\t\t\tHash:  *hash,\n\t\t\tForce: true,\n\t\t}); err != nil {\n\t\t\tlogger.Errorf(\"Unable to checkout %s: %v\", *hash, err)\n\t\t\treturn err\n\t\t}\n\n\t\tif err = w.Reset(&git.ResetOptions{\n\t\t\tMode:   git.HardReset,\n\t\t\tCommit: *hash,\n\t\t}); err != nil {\n\t\t\tlogger.Errorf(\"Unable to reset to %s: %v\", hash.String(), err)\n\t\t\treturn err\n\t\t}\n\n\t\tlogger.Debugf(\"Checked out %s\", input.Ref)\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "pkg/common/git/git_test.go",
    "content": "package git\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"syscall\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/nektos/act/pkg/common\"\n)\n\nfunc TestFindGitSlug(t *testing.T) {\n\tassert := assert.New(t)\n\n\tvar slugTests = []struct {\n\t\turl      string // input\n\t\tprovider string // expected result\n\t\tslug     string // expected result\n\t}{\n\t\t{\"https://git-codecommit.us-east-1.amazonaws.com/v1/repos/my-repo-name\", \"CodeCommit\", \"my-repo-name\"},\n\t\t{\"ssh://git-codecommit.us-west-2.amazonaws.com/v1/repos/my-repo\", \"CodeCommit\", \"my-repo\"},\n\t\t{\"git@github.com:nektos/act.git\", \"GitHub\", \"nektos/act\"},\n\t\t{\"git@github.com:nektos/act\", \"GitHub\", \"nektos/act\"},\n\t\t{\"https://github.com/nektos/act.git\", \"GitHub\", \"nektos/act\"},\n\t\t{\"http://github.com/nektos/act.git\", \"GitHub\", \"nektos/act\"},\n\t\t{\"https://github.com/nektos/act\", \"GitHub\", \"nektos/act\"},\n\t\t{\"http://github.com/nektos/act\", \"GitHub\", \"nektos/act\"},\n\t\t{\"git+ssh://git@github.com/owner/repo.git\", \"GitHub\", \"owner/repo\"},\n\t\t{\"http://myotherrepo.com/act.git\", \"\", \"http://myotherrepo.com/act.git\"},\n\t}\n\n\tfor _, tt := range slugTests {\n\t\tprovider, slug, err := findGitSlug(tt.url, \"github.com\")\n\n\t\tassert.NoError(err)\n\t\tassert.Equal(tt.provider, provider)\n\t\tassert.Equal(tt.slug, slug)\n\t}\n}\n\nfunc testDir(t *testing.T) string {\n\tbasedir, err := os.MkdirTemp(\"\", \"act-test\")\n\trequire.NoError(t, err)\n\tt.Cleanup(func() { _ = os.RemoveAll(basedir) })\n\treturn basedir\n}\n\nfunc cleanGitHooks(dir string) error {\n\thooksDir := filepath.Join(dir, \".git\", \"hooks\")\n\tfiles, err := os.ReadDir(hooksDir)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\tfor _, f := range files {\n\t\tif f.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\trelName := filepath.Join(hooksDir, f.Name())\n\t\tif err := os.Remove(relName); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc TestFindGitRemoteURL(t *testing.T) {\n\tassert := assert.New(t)\n\n\tbasedir := testDir(t)\n\tgitConfig()\n\terr := gitCmd(\"init\", basedir)\n\tassert.NoError(err)\n\terr = cleanGitHooks(basedir)\n\tassert.NoError(err)\n\n\tremoteURL := \"https://git-codecommit.us-east-1.amazonaws.com/v1/repos/my-repo-name\"\n\terr = gitCmd(\"-C\", basedir, \"remote\", \"add\", \"origin\", remoteURL)\n\tassert.NoError(err)\n\n\tu, err := findGitRemoteURL(context.Background(), basedir, \"origin\")\n\tassert.NoError(err)\n\tassert.Equal(remoteURL, u)\n\n\tremoteURL = \"git@github.com/AwesomeOwner/MyAwesomeRepo.git\"\n\terr = gitCmd(\"-C\", basedir, \"remote\", \"add\", \"upstream\", remoteURL)\n\tassert.NoError(err)\n\tu, err = findGitRemoteURL(context.Background(), basedir, \"upstream\")\n\tassert.NoError(err)\n\tassert.Equal(remoteURL, u)\n}\n\nfunc TestGitFindRef(t *testing.T) {\n\tbasedir := testDir(t)\n\tgitConfig()\n\n\tfor name, tt := range map[string]struct {\n\t\tPrepare func(t *testing.T, dir string)\n\t\tAssert  func(t *testing.T, ref string, err error)\n\t}{\n\t\t\"new_repo\": {\n\t\t\tPrepare: func(_ *testing.T, _ string) {},\n\t\t\tAssert: func(t *testing.T, _ string, err error) {\n\t\t\t\trequire.Error(t, err)\n\t\t\t},\n\t\t},\n\t\t\"new_repo_with_commit\": {\n\t\t\tPrepare: func(t *testing.T, dir string) {\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"commit\", \"--allow-empty\", \"-m\", \"msg\"))\n\t\t\t},\n\t\t\tAssert: func(t *testing.T, ref string, err error) {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, \"refs/heads/master\", ref)\n\t\t\t},\n\t\t},\n\t\t\"current_head_is_tag\": {\n\t\t\tPrepare: func(t *testing.T, dir string) {\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"commit\", \"--allow-empty\", \"-m\", \"commit msg\"))\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"tag\", \"v1.2.3\"))\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"checkout\", \"v1.2.3\"))\n\t\t\t},\n\t\t\tAssert: func(t *testing.T, ref string, err error) {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, \"refs/tags/v1.2.3\", ref)\n\t\t\t},\n\t\t},\n\t\t\"current_head_is_same_as_tag\": {\n\t\t\tPrepare: func(t *testing.T, dir string) {\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"commit\", \"--allow-empty\", \"-m\", \"1.4.2 release\"))\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"tag\", \"v1.4.2\"))\n\t\t\t},\n\t\t\tAssert: func(t *testing.T, ref string, err error) {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, \"refs/tags/v1.4.2\", ref)\n\t\t\t},\n\t\t},\n\t\t\"current_head_is_not_tag\": {\n\t\t\tPrepare: func(t *testing.T, dir string) {\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"commit\", \"--allow-empty\", \"-m\", \"msg\"))\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"tag\", \"v1.4.2\"))\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"commit\", \"--allow-empty\", \"-m\", \"msg2\"))\n\t\t\t},\n\t\t\tAssert: func(t *testing.T, ref string, err error) {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, \"refs/heads/master\", ref)\n\t\t\t},\n\t\t},\n\t\t\"current_head_is_another_branch\": {\n\t\t\tPrepare: func(t *testing.T, dir string) {\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"checkout\", \"-b\", \"mybranch\"))\n\t\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"commit\", \"--allow-empty\", \"-m\", \"msg\"))\n\t\t\t},\n\t\t\tAssert: func(t *testing.T, ref string, err error) {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, \"refs/heads/mybranch\", ref)\n\t\t\t},\n\t\t},\n\t} {\n\t\tt.Run(name, func(t *testing.T) {\n\t\t\tdir := filepath.Join(basedir, name)\n\t\t\trequire.NoError(t, os.MkdirAll(dir, 0o755))\n\t\t\trequire.NoError(t, gitCmd(\"-C\", dir, \"init\", \"--initial-branch=master\"))\n\t\t\trequire.NoError(t, cleanGitHooks(dir))\n\t\t\ttt.Prepare(t, dir)\n\t\t\tref, err := FindGitRef(context.Background(), dir)\n\t\t\ttt.Assert(t, ref, err)\n\t\t})\n\t}\n}\n\nfunc TestGitCloneExecutor(t *testing.T) {\n\tfor name, tt := range map[string]struct {\n\t\tErr      error\n\t\tURL, Ref string\n\t}{\n\t\t\"tag\": {\n\t\t\tErr: nil,\n\t\t\tURL: \"https://github.com/actions/checkout\",\n\t\t\tRef: \"v2\",\n\t\t},\n\t\t\"branch\": {\n\t\t\tErr: nil,\n\t\t\tURL: \"https://github.com/anchore/scan-action\",\n\t\t\tRef: \"act-fails\",\n\t\t},\n\t\t\"sha\": {\n\t\t\tErr: nil,\n\t\t\tURL: \"https://github.com/actions/checkout\",\n\t\t\tRef: \"5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f\", // v2\n\t\t},\n\t\t\"short-sha\": {\n\t\t\tErr: &Error{ErrShortRef, \"5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f\"},\n\t\t\tURL: \"https://github.com/actions/checkout\",\n\t\t\tRef: \"5a4ac90\", // v2\n\t\t},\n\t} {\n\t\tt.Run(name, func(t *testing.T) {\n\t\t\tclone := NewGitCloneExecutor(NewGitCloneExecutorInput{\n\t\t\t\tURL: tt.URL,\n\t\t\t\tRef: tt.Ref,\n\t\t\t\tDir: testDir(t),\n\t\t\t})\n\n\t\t\terr := clone(context.Background())\n\t\t\tif tt.Err != nil {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\tassert.Equal(t, tt.Err, err)\n\t\t\t} else {\n\t\t\t\tassert.Empty(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc gitConfig() {\n\tif os.Getenv(\"GITHUB_ACTIONS\") == \"true\" {\n\t\tvar err error\n\t\tif err = gitCmd(\"config\", \"--global\", \"user.email\", \"test@test.com\"); err != nil {\n\t\t\tlog.Error(err)\n\t\t}\n\t\tif err = gitCmd(\"config\", \"--global\", \"user.name\", \"Unit Test\"); err != nil {\n\t\t\tlog.Error(err)\n\t\t}\n\t}\n}\n\nfunc gitCmd(args ...string) error {\n\tcmd := exec.Command(\"git\", args...)\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\n\terr := cmd.Run()\n\tif exitError, ok := err.(*exec.ExitError); ok {\n\t\tif waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {\n\t\t\treturn fmt.Errorf(\"Exit error %d\", waitStatus.ExitStatus())\n\t\t}\n\t\treturn exitError\n\t}\n\treturn nil\n}\n\nfunc TestCloneIfRequired(t *testing.T) {\n\ttempDir := t.TempDir()\n\tctx := context.Background()\n\n\tt.Run(\"clone\", func(t *testing.T) {\n\t\trepo, err := CloneIfRequired(ctx, \"refs/heads/main\", NewGitCloneExecutorInput{\n\t\t\tURL: \"https://github.com/actions/checkout\",\n\t\t\tDir: tempDir,\n\t\t}, common.Logger(ctx))\n\t\tassert.NoError(t, err)\n\t\tassert.NotNil(t, repo)\n\t})\n\n\tt.Run(\"clone different remote\", func(t *testing.T) {\n\t\trepo, err := CloneIfRequired(ctx, \"refs/heads/main\", NewGitCloneExecutorInput{\n\t\t\tURL: \"https://github.com/actions/setup-go\",\n\t\t\tDir: tempDir,\n\t\t}, common.Logger(ctx))\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, repo)\n\n\t\tremote, err := repo.Remote(\"origin\")\n\t\trequire.NoError(t, err)\n\t\trequire.Len(t, remote.Config().URLs, 1)\n\t\tassert.Equal(t, \"https://github.com/actions/setup-go\", remote.Config().URLs[0])\n\t})\n}\n"
  },
  {
    "path": "pkg/common/job_error.go",
    "content": "package common\n\nimport (\n\t\"context\"\n)\n\ntype jobErrorContextKey string\n\nconst jobErrorContextKeyVal = jobErrorContextKey(\"job.error\")\n\ntype jobCancelCtx string\n\nconst JobCancelCtxVal = jobCancelCtx(\"job.cancel\")\n\n// JobError returns the job error for current context if any\nfunc JobError(ctx context.Context) error {\n\tval := ctx.Value(jobErrorContextKeyVal)\n\tif val != nil {\n\t\tif container, ok := val.(map[string]error); ok {\n\t\t\treturn container[\"error\"]\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc SetJobError(ctx context.Context, err error) {\n\tctx.Value(jobErrorContextKeyVal).(map[string]error)[\"error\"] = err\n}\n\n// WithJobErrorContainer adds a value to the context as a container for an error\nfunc WithJobErrorContainer(ctx context.Context) context.Context {\n\tcontainer := map[string]error{}\n\treturn context.WithValue(ctx, jobErrorContextKeyVal, container)\n}\n\nfunc WithJobCancelContext(ctx context.Context, cancelContext context.Context) context.Context {\n\treturn context.WithValue(ctx, JobCancelCtxVal, cancelContext)\n}\n\nfunc JobCancelContext(ctx context.Context) context.Context {\n\tval := ctx.Value(JobCancelCtxVal)\n\tif val != nil {\n\t\tif container, ok := val.(context.Context); ok {\n\t\t\treturn container\n\t\t}\n\t}\n\treturn nil\n}\n\n// EarlyCancelContext returns a new context based on ctx that is canceled when the first of the provided contexts is canceled.\nfunc EarlyCancelContext(ctx context.Context) (context.Context, context.CancelFunc) {\n\tval := JobCancelContext(ctx)\n\tif val != nil {\n\t\tcontext, cancel := context.WithCancel(ctx)\n\t\tgo func() {\n\t\t\tdefer cancel()\n\t\t\tselect {\n\t\t\tcase <-context.Done():\n\t\t\tcase <-ctx.Done():\n\t\t\tcase <-val.Done():\n\t\t\t}\n\t\t}()\n\t\treturn context, cancel\n\t}\n\treturn ctx, func() {}\n}\n"
  },
  {
    "path": "pkg/common/line_writer.go",
    "content": "package common\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\n// LineHandler is a callback function for handling a line\ntype LineHandler func(line string) bool\n\ntype lineWriter struct {\n\tbuffer   bytes.Buffer\n\thandlers []LineHandler\n}\n\n// NewLineWriter creates a new instance of a line writer\nfunc NewLineWriter(handlers ...LineHandler) io.Writer {\n\tw := new(lineWriter)\n\tw.handlers = handlers\n\treturn w\n}\n\nfunc (lw *lineWriter) Write(p []byte) (n int, err error) {\n\tpBuf := bytes.NewBuffer(p)\n\twritten := 0\n\tfor {\n\t\tline, err := pBuf.ReadString('\\n')\n\t\tw, _ := lw.buffer.WriteString(line)\n\t\twritten += w\n\t\tif err == nil {\n\t\t\tlw.handleLine(lw.buffer.String())\n\t\t\tlw.buffer.Reset()\n\t\t} else if err == io.EOF {\n\t\t\tbreak\n\t\t} else {\n\t\t\treturn written, err\n\t\t}\n\t}\n\n\treturn written, nil\n}\n\nfunc (lw *lineWriter) handleLine(line string) {\n\tfor _, h := range lw.handlers {\n\t\tok := h(line)\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/common/line_writer_test.go",
    "content": "package common\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestLineWriter(t *testing.T) {\n\tlines := make([]string, 0)\n\tlineHandler := func(s string) bool {\n\t\tlines = append(lines, s)\n\t\treturn true\n\t}\n\n\tlineWriter := NewLineWriter(lineHandler)\n\n\tassert := assert.New(t)\n\twrite := func(s string) {\n\t\tn, err := lineWriter.Write([]byte(s))\n\t\tassert.NoError(err)\n\t\tassert.Equal(len(s), n, s)\n\t}\n\n\twrite(\"hello\")\n\twrite(\" \")\n\twrite(\"world!!\\nextra\")\n\twrite(\" line\\n and another\\nlast\")\n\twrite(\" line\\n\")\n\twrite(\"no newline here...\")\n\n\tassert.Len(lines, 4)\n\tassert.Equal(\"hello world!!\\n\", lines[0])\n\tassert.Equal(\"extra line\\n\", lines[1])\n\tassert.Equal(\" and another\\n\", lines[2])\n\tassert.Equal(\"last line\\n\", lines[3])\n}\n"
  },
  {
    "path": "pkg/common/logger.go",
    "content": "package common\n\nimport (\n\t\"context\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\ntype loggerContextKey string\n\nconst loggerContextKeyVal = loggerContextKey(\"logrus.FieldLogger\")\n\n// Logger returns the appropriate logger for current context\nfunc Logger(ctx context.Context) logrus.FieldLogger {\n\tval := ctx.Value(loggerContextKeyVal)\n\tif val != nil {\n\t\tif logger, ok := val.(logrus.FieldLogger); ok {\n\t\t\treturn logger\n\t\t}\n\t}\n\treturn logrus.StandardLogger()\n}\n\n// WithLogger adds a value to the context for the logger\nfunc WithLogger(ctx context.Context, logger logrus.FieldLogger) context.Context {\n\treturn context.WithValue(ctx, loggerContextKeyVal, logger)\n}\n"
  },
  {
    "path": "pkg/common/outbound_ip.go",
    "content": "package common\n\nimport (\n\t\"net\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// GetOutboundIP returns an outbound IP address of this machine.\n// It tries to access the internet and returns the local IP address of the connection.\n// If the machine cannot access the internet, it returns a preferred IP address from network interfaces.\n// It returns nil if no IP address is found.\nfunc GetOutboundIP() net.IP {\n\t// See https://stackoverflow.com/a/37382208\n\tconn, err := net.Dial(\"udp\", \"8.8.8.8:80\")\n\tif err == nil {\n\t\tdefer conn.Close()\n\t\treturn conn.LocalAddr().(*net.UDPAddr).IP\n\t}\n\n\t// So the machine cannot access the internet. Pick an IP address from network interfaces.\n\tif ifs, err := net.Interfaces(); err == nil {\n\t\ttype IP struct {\n\t\t\tnet.IP\n\t\t\tnet.Interface\n\t\t}\n\t\tvar ips []IP\n\t\tfor _, i := range ifs {\n\t\t\tif addrs, err := i.Addrs(); err == nil {\n\t\t\t\tfor _, addr := range addrs {\n\t\t\t\t\tvar ip net.IP\n\t\t\t\t\tswitch v := addr.(type) {\n\t\t\t\t\tcase *net.IPNet:\n\t\t\t\t\t\tip = v.IP\n\t\t\t\t\tcase *net.IPAddr:\n\t\t\t\t\t\tip = v.IP\n\t\t\t\t\t}\n\t\t\t\t\tif ip.IsGlobalUnicast() {\n\t\t\t\t\t\tips = append(ips, IP{ip, i})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif len(ips) > 1 {\n\t\t\tsort.Slice(ips, func(i, j int) bool {\n\t\t\t\tifi := ips[i].Interface\n\t\t\t\tifj := ips[j].Interface\n\n\t\t\t\t// ethernet is preferred\n\t\t\t\tif vi, vj := strings.HasPrefix(ifi.Name, \"e\"), strings.HasPrefix(ifj.Name, \"e\"); vi != vj {\n\t\t\t\t\treturn vi\n\t\t\t\t}\n\n\t\t\t\tipi := ips[i].IP\n\t\t\t\tipj := ips[j].IP\n\n\t\t\t\t// IPv4 is preferred\n\t\t\t\tif vi, vj := ipi.To4() != nil, ipj.To4() != nil; vi != vj {\n\t\t\t\t\treturn vi\n\t\t\t\t}\n\n\t\t\t\t// en0 is preferred to en1\n\t\t\t\tif ifi.Name != ifj.Name {\n\t\t\t\t\treturn ifi.Name < ifj.Name\n\t\t\t\t}\n\n\t\t\t\t// fallback\n\t\t\t\treturn ipi.String() < ipj.String()\n\t\t\t})\n\t\t\treturn ips[0].IP\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/container/DOCKER_LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        https://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   Copyright 2013-2017 Docker, Inc.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       https://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "pkg/container/container_types.go",
    "content": "package container\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/docker/go-connections/nat\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\n// NewContainerInput the input for the New function\ntype NewContainerInput struct {\n\tImage          string\n\tUsername       string\n\tPassword       string\n\tEntrypoint     []string\n\tCmd            []string\n\tWorkingDir     string\n\tEnv            []string\n\tBinds          []string\n\tMounts         map[string]string\n\tName           string\n\tStdout         io.Writer\n\tStderr         io.Writer\n\tNetworkMode    string\n\tPrivileged     bool\n\tUsernsMode     string\n\tPlatform       string\n\tOptions        string\n\tNetworkAliases []string\n\tExposedPorts   nat.PortSet\n\tPortBindings   nat.PortMap\n}\n\n// FileEntry is a file to copy to a container\ntype FileEntry struct {\n\tName string\n\tMode uint32\n\tBody string\n}\n\n// Container for managing docker run containers\ntype Container interface {\n\tCreate(capAdd []string, capDrop []string) common.Executor\n\tCopy(destPath string, files ...*FileEntry) common.Executor\n\tCopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error\n\tCopyDir(destPath string, srcPath string, useGitIgnore bool) common.Executor\n\tGetContainerArchive(ctx context.Context, srcPath string) (io.ReadCloser, error)\n\tPull(forcePull bool) common.Executor\n\tStart(attach bool) common.Executor\n\tExec(command []string, env map[string]string, user, workdir string) common.Executor\n\tUpdateFromEnv(srcPath string, env *map[string]string) common.Executor\n\tUpdateFromImageEnv(env *map[string]string) common.Executor\n\tRemove() common.Executor\n\tClose() common.Executor\n\tReplaceLogWriter(io.Writer, io.Writer) (io.Writer, io.Writer)\n\tGetHealth(ctx context.Context) Health\n}\n\n// NewDockerBuildExecutorInput the input for the NewDockerBuildExecutor function\ntype NewDockerBuildExecutorInput struct {\n\tContextDir   string\n\tDockerfile   string\n\tBuildContext io.Reader\n\tImageTag     string\n\tPlatform     string\n}\n\n// NewDockerPullExecutorInput the input for the NewDockerPullExecutor function\ntype NewDockerPullExecutorInput struct {\n\tImage     string\n\tForcePull bool\n\tPlatform  string\n\tUsername  string\n\tPassword  string\n}\n\ntype Health int\n\nconst (\n\tHealthStarting Health = iota\n\tHealthHealthy\n\tHealthUnHealthy\n)\n"
  },
  {
    "path": "pkg/container/docker_auth.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/docker/cli/cli/config\"\n\t\"github.com/docker/cli/cli/config/credentials\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\nfunc LoadDockerAuthConfig(ctx context.Context, image string) (registry.AuthConfig, error) {\n\tlogger := common.Logger(ctx)\n\tconfig, err := config.Load(config.Dir())\n\tif err != nil {\n\t\tlogger.Warnf(\"Could not load docker config: %v\", err)\n\t\treturn registry.AuthConfig{}, err\n\t}\n\n\tif !config.ContainsAuth() {\n\t\tconfig.CredentialsStore = credentials.DetectDefaultStore(config.CredentialsStore)\n\t}\n\n\thostName := \"index.docker.io\"\n\tindex := strings.IndexRune(image, '/')\n\tif index > -1 && (strings.ContainsAny(image[:index], \".:\") || image[:index] == \"localhost\") {\n\t\thostName = image[:index]\n\t}\n\n\tauthConfig, err := config.GetAuthConfig(hostName)\n\tif err != nil {\n\t\tlogger.Warnf(\"Could not get auth config from docker config: %v\", err)\n\t\treturn registry.AuthConfig{}, err\n\t}\n\n\treturn registry.AuthConfig(authConfig), nil\n}\n\nfunc LoadDockerAuthConfigs(ctx context.Context) map[string]registry.AuthConfig {\n\tlogger := common.Logger(ctx)\n\tconfig, err := config.Load(config.Dir())\n\tif err != nil {\n\t\tlogger.Warnf(\"Could not load docker config: %v\", err)\n\t\treturn nil\n\t}\n\n\tif !config.ContainsAuth() {\n\t\tconfig.CredentialsStore = credentials.DetectDefaultStore(config.CredentialsStore)\n\t}\n\n\tcreds, _ := config.GetAllCredentials()\n\tauthConfigs := make(map[string]registry.AuthConfig, len(creds))\n\tfor k, v := range creds {\n\t\tauthConfigs[k] = registry.AuthConfig(v)\n\t}\n\n\treturn authConfigs\n}\n"
  },
  {
    "path": "pkg/container/docker_build.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/docker/docker/api/types/build\"\n\t\"github.com/moby/go-archive\"\n\n\t\"github.com/moby/patternmatcher\"\n\t\"github.com/moby/patternmatcher/ignorefile\"\n\n\t\"github.com/nektos/act/pkg/common\"\n)\n\n// NewDockerBuildExecutor function to create a run executor for the container\nfunc NewDockerBuildExecutor(input NewDockerBuildExecutorInput) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tif input.Platform != \"\" {\n\t\t\tlogger.Infof(\"%sdocker build -t %s --platform %s %s\", logPrefix, input.ImageTag, input.Platform, input.ContextDir)\n\t\t} else {\n\t\t\tlogger.Infof(\"%sdocker build -t %s %s\", logPrefix, input.ImageTag, input.ContextDir)\n\t\t}\n\t\tif common.Dryrun(ctx) {\n\t\t\treturn nil\n\t\t}\n\n\t\tcli, err := GetDockerClient(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer cli.Close()\n\n\t\tlogger.Debugf(\"Building image from '%v'\", input.ContextDir)\n\n\t\ttags := []string{input.ImageTag}\n\t\toptions := build.ImageBuildOptions{\n\t\t\tTags:        tags,\n\t\t\tRemove:      true,\n\t\t\tPlatform:    input.Platform,\n\t\t\tAuthConfigs: LoadDockerAuthConfigs(ctx),\n\t\t\tDockerfile:  input.Dockerfile,\n\t\t}\n\t\tvar buildContext io.ReadCloser\n\t\tif input.BuildContext != nil {\n\t\t\tbuildContext = io.NopCloser(input.BuildContext)\n\t\t} else {\n\t\t\tbuildContext, err = createBuildContext(ctx, input.ContextDir, input.Dockerfile)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tdefer buildContext.Close()\n\n\t\tlogger.Debugf(\"Creating image from context dir '%s' with tag '%s' and platform '%s'\", input.ContextDir, input.ImageTag, input.Platform)\n\t\tresp, err := cli.ImageBuild(ctx, buildContext, options)\n\n\t\terr = logDockerResponse(logger, resp.Body, err != nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n}\nfunc createBuildContext(ctx context.Context, contextDir string, relDockerfile string) (io.ReadCloser, error) {\n\tcommon.Logger(ctx).Debugf(\"Creating archive for build context dir '%s' with relative dockerfile '%s'\", contextDir, relDockerfile)\n\n\t// And canonicalize dockerfile name to a platform-independent one\n\trelDockerfile = filepath.ToSlash(relDockerfile)\n\n\tf, err := os.Open(filepath.Join(contextDir, \".dockerignore\"))\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\tvar excludes []string\n\tif err == nil {\n\t\texcludes, err = ignorefile.ReadAll(f)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// If .dockerignore mentions .dockerignore or the Dockerfile\n\t// then make sure we send both files over to the daemon\n\t// because Dockerfile is, obviously, needed no matter what, and\n\t// .dockerignore is needed to know if either one needs to be\n\t// removed. The daemon will remove them for us, if needed, after it\n\t// parses the Dockerfile. Ignore errors here, as they will have been\n\t// caught by validateContextDirectory above.\n\tvar includes = []string{\".\"}\n\tkeepThem1, _ := patternmatcher.Matches(\".dockerignore\", excludes)\n\tkeepThem2, _ := patternmatcher.Matches(relDockerfile, excludes)\n\tif keepThem1 || keepThem2 {\n\t\tincludes = append(includes, \".dockerignore\", relDockerfile)\n\t}\n\n\tcompression := archive.Uncompressed\n\tbuildCtx, err := archive.TarWithOptions(contextDir, &archive.TarOptions{\n\t\tCompression:     compression,\n\t\tExcludePatterns: excludes,\n\t\tIncludeFiles:    includes,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn buildCtx, nil\n}\n"
  },
  {
    "path": "pkg/container/docker_cli.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\n// This file is exact copy of https://github.com/docker/cli/blob/9ac8584acfd501c3f4da0e845e3a40ed15c85041/cli/command/container/opts.go\n// appended with license information.\n//\n// docker/cli is licensed under the Apache License, Version 2.0.\n// See DOCKER_LICENSE for the full license text.\n//\n\n//nolint:unparam,errcheck,depguard,deadcode,unused\npackage container\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/docker/cli/cli/compose/loader\"\n\t\"github.com/docker/cli/opts\"\n\t\"github.com/docker/docker/api/types/container\"\n\tmounttypes \"github.com/docker/docker/api/types/mount\"\n\tnetworktypes \"github.com/docker/docker/api/types/network\"\n\t\"github.com/docker/docker/api/types/strslice\"\n\t\"github.com/docker/docker/api/types/versions\"\n\t\"github.com/docker/docker/errdefs\"\n\t\"github.com/docker/go-connections/nat\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar (\n\tdeviceCgroupRuleRegexp = regexp.MustCompile(`^[acb] ([0-9]+|\\*):([0-9]+|\\*) [rwm]{1,3}$`)\n)\n\n// containerOptions is a data object with all the options for creating a container\ntype containerOptions struct {\n\tattach             opts.ListOpts\n\tvolumes            opts.ListOpts\n\ttmpfs              opts.ListOpts\n\tmounts             opts.MountOpt\n\tblkioWeightDevice  opts.WeightdeviceOpt\n\tdeviceReadBps      opts.ThrottledeviceOpt\n\tdeviceWriteBps     opts.ThrottledeviceOpt\n\tlinks              opts.ListOpts\n\taliases            opts.ListOpts\n\tlinkLocalIPs       opts.ListOpts\n\tdeviceReadIOps     opts.ThrottledeviceOpt\n\tdeviceWriteIOps    opts.ThrottledeviceOpt\n\tenv                opts.ListOpts\n\tlabels             opts.ListOpts\n\tdeviceCgroupRules  opts.ListOpts\n\tdevices            opts.ListOpts\n\tgpus               opts.GpuOpts\n\tulimits            *opts.UlimitOpt\n\tsysctls            *opts.MapOpts\n\tpublish            opts.ListOpts\n\texpose             opts.ListOpts\n\tdns                opts.ListOpts\n\tdnsSearch          opts.ListOpts\n\tdnsOptions         opts.ListOpts\n\textraHosts         opts.ListOpts\n\tvolumesFrom        opts.ListOpts\n\tenvFile            opts.ListOpts\n\tcapAdd             opts.ListOpts\n\tcapDrop            opts.ListOpts\n\tgroupAdd           opts.ListOpts\n\tsecurityOpt        opts.ListOpts\n\tstorageOpt         opts.ListOpts\n\tlabelsFile         opts.ListOpts\n\tloggingOpts        opts.ListOpts\n\tprivileged         bool\n\tpidMode            string\n\tutsMode            string\n\tusernsMode         string\n\tcgroupnsMode       string\n\tpublishAll         bool\n\tstdin              bool\n\ttty                bool\n\toomKillDisable     bool\n\toomScoreAdj        int\n\tcontainerIDFile    string\n\tentrypoint         string\n\thostname           string\n\tdomainname         string\n\tmemory             opts.MemBytes\n\tmemoryReservation  opts.MemBytes\n\tmemorySwap         opts.MemSwapBytes\n\tkernelMemory       opts.MemBytes\n\tuser               string\n\tworkingDir         string\n\tcpuCount           int64\n\tcpuShares          int64\n\tcpuPercent         int64\n\tcpuPeriod          int64\n\tcpuRealtimePeriod  int64\n\tcpuRealtimeRuntime int64\n\tcpuQuota           int64\n\tcpus               opts.NanoCPUs\n\tcpusetCpus         string\n\tcpusetMems         string\n\tblkioWeight        uint16\n\tioMaxBandwidth     uint64\n\tioMaxIOps          uint64\n\tswappiness         int64\n\tnetMode            opts.NetworkOpt\n\tmacAddress         string\n\tipv4Address        string\n\tipv6Address        string\n\tipcMode            string\n\tpidsLimit          int64\n\trestartPolicy      string\n\treadonlyRootfs     bool\n\tloggingDriver      string\n\tcgroupParent       string\n\tvolumeDriver       string\n\tstopSignal         string\n\tstopTimeout        int\n\tisolation          string\n\tshmSize            opts.MemBytes\n\tnoHealthcheck      bool\n\thealthCmd          string\n\thealthInterval     time.Duration\n\thealthTimeout      time.Duration\n\thealthStartPeriod  time.Duration\n\thealthRetries      int\n\truntime            string\n\tautoRemove         bool\n\tinit               bool\n\n\tImage string\n\tArgs  []string\n}\n\n// addFlags adds all command line flags that will be used by parse to the FlagSet\nfunc addFlags(flags *pflag.FlagSet) *containerOptions {\n\tcopts := &containerOptions{\n\t\taliases:           opts.NewListOpts(nil),\n\t\tattach:            opts.NewListOpts(validateAttach),\n\t\tblkioWeightDevice: opts.NewWeightdeviceOpt(opts.ValidateWeightDevice),\n\t\tcapAdd:            opts.NewListOpts(nil),\n\t\tcapDrop:           opts.NewListOpts(nil),\n\t\tdns:               opts.NewListOpts(opts.ValidateIPAddress),\n\t\tdnsOptions:        opts.NewListOpts(nil),\n\t\tdnsSearch:         opts.NewListOpts(opts.ValidateDNSSearch),\n\t\tdeviceCgroupRules: opts.NewListOpts(validateDeviceCgroupRule),\n\t\tdeviceReadBps:     opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice),\n\t\tdeviceReadIOps:    opts.NewThrottledeviceOpt(opts.ValidateThrottleIOpsDevice),\n\t\tdeviceWriteBps:    opts.NewThrottledeviceOpt(opts.ValidateThrottleBpsDevice),\n\t\tdeviceWriteIOps:   opts.NewThrottledeviceOpt(opts.ValidateThrottleIOpsDevice),\n\t\tdevices:           opts.NewListOpts(nil), // devices can only be validated after we know the server OS\n\t\tenv:               opts.NewListOpts(opts.ValidateEnv),\n\t\tenvFile:           opts.NewListOpts(nil),\n\t\texpose:            opts.NewListOpts(nil),\n\t\textraHosts:        opts.NewListOpts(opts.ValidateExtraHost),\n\t\tgroupAdd:          opts.NewListOpts(nil),\n\t\tlabels:            opts.NewListOpts(opts.ValidateLabel),\n\t\tlabelsFile:        opts.NewListOpts(nil),\n\t\tlinkLocalIPs:      opts.NewListOpts(nil),\n\t\tlinks:             opts.NewListOpts(opts.ValidateLink),\n\t\tloggingOpts:       opts.NewListOpts(nil),\n\t\tpublish:           opts.NewListOpts(nil),\n\t\tsecurityOpt:       opts.NewListOpts(nil),\n\t\tstorageOpt:        opts.NewListOpts(nil),\n\t\tsysctls:           opts.NewMapOpts(nil, opts.ValidateSysctl),\n\t\ttmpfs:             opts.NewListOpts(nil),\n\t\tulimits:           opts.NewUlimitOpt(nil),\n\t\tvolumes:           opts.NewListOpts(nil),\n\t\tvolumesFrom:       opts.NewListOpts(nil),\n\t}\n\n\t// General purpose flags\n\tflags.VarP(&copts.attach, \"attach\", \"a\", \"Attach to STDIN, STDOUT or STDERR\")\n\tflags.Var(&copts.deviceCgroupRules, \"device-cgroup-rule\", \"Add a rule to the cgroup allowed devices list\")\n\tflags.Var(&copts.devices, \"device\", \"Add a host device to the container\")\n\tflags.Var(&copts.gpus, \"gpus\", \"GPU devices to add to the container ('all' to pass all GPUs)\")\n\tflags.SetAnnotation(\"gpus\", \"version\", []string{\"1.40\"})\n\tflags.VarP(&copts.env, \"env\", \"e\", \"Set environment variables\")\n\tflags.Var(&copts.envFile, \"env-file\", \"Read in a file of environment variables\")\n\tflags.StringVar(&copts.entrypoint, \"entrypoint\", \"\", \"Overwrite the default ENTRYPOINT of the image\")\n\tflags.Var(&copts.groupAdd, \"group-add\", \"Add additional groups to join\")\n\tflags.StringVarP(&copts.hostname, \"hostname\", \"h\", \"\", \"Container host name\")\n\tflags.StringVar(&copts.domainname, \"domainname\", \"\", \"Container NIS domain name\")\n\tflags.BoolVarP(&copts.stdin, \"interactive\", \"i\", false, \"Keep STDIN open even if not attached\")\n\tflags.VarP(&copts.labels, \"label\", \"l\", \"Set meta data on a container\")\n\tflags.Var(&copts.labelsFile, \"label-file\", \"Read in a line delimited file of labels\")\n\tflags.BoolVar(&copts.readonlyRootfs, \"read-only\", false, \"Mount the container's root filesystem as read only\")\n\tflags.StringVar(&copts.restartPolicy, \"restart\", \"no\", \"Restart policy to apply when a container exits\")\n\tflags.StringVar(&copts.stopSignal, \"stop-signal\", \"\", \"Signal to stop the container\")\n\tflags.IntVar(&copts.stopTimeout, \"stop-timeout\", 0, \"Timeout (in seconds) to stop a container\")\n\tflags.SetAnnotation(\"stop-timeout\", \"version\", []string{\"1.25\"})\n\tflags.Var(copts.sysctls, \"sysctl\", \"Sysctl options\")\n\tflags.BoolVarP(&copts.tty, \"tty\", \"t\", false, \"Allocate a pseudo-TTY\")\n\tflags.Var(copts.ulimits, \"ulimit\", \"Ulimit options\")\n\tflags.StringVarP(&copts.user, \"user\", \"u\", \"\", \"Username or UID (format: <name|uid>[:<group|gid>])\")\n\tflags.StringVarP(&copts.workingDir, \"workdir\", \"w\", \"\", \"Working directory inside the container\")\n\tflags.BoolVar(&copts.autoRemove, \"rm\", false, \"Automatically remove the container when it exits\")\n\n\t// Security\n\tflags.Var(&copts.capAdd, \"cap-add\", \"Add Linux capabilities\")\n\tflags.Var(&copts.capDrop, \"cap-drop\", \"Drop Linux capabilities\")\n\tflags.BoolVar(&copts.privileged, \"privileged\", false, \"Give extended privileges to this container\")\n\tflags.Var(&copts.securityOpt, \"security-opt\", \"Security Options\")\n\tflags.StringVar(&copts.usernsMode, \"userns\", \"\", \"User namespace to use\")\n\tflags.StringVar(&copts.cgroupnsMode, \"cgroupns\", \"\", `Cgroup namespace to use (host|private)\n'host':    Run the container in the Docker host's cgroup namespace\n'private': Run the container in its own private cgroup namespace\n'':        Use the cgroup namespace as configured by the\n           default-cgroupns-mode option on the daemon (default)`)\n\tflags.SetAnnotation(\"cgroupns\", \"version\", []string{\"1.41\"})\n\n\t// Network and port publishing flag\n\tflags.Var(&copts.extraHosts, \"add-host\", \"Add a custom host-to-IP mapping (host:ip)\")\n\tflags.Var(&copts.dns, \"dns\", \"Set custom DNS servers\")\n\t// We allow for both \"--dns-opt\" and \"--dns-option\", although the latter is the recommended way.\n\t// This is to be consistent with service create/update\n\tflags.Var(&copts.dnsOptions, \"dns-opt\", \"Set DNS options\")\n\tflags.Var(&copts.dnsOptions, \"dns-option\", \"Set DNS options\")\n\tflags.MarkHidden(\"dns-opt\")\n\tflags.Var(&copts.dnsSearch, \"dns-search\", \"Set custom DNS search domains\")\n\tflags.Var(&copts.expose, \"expose\", \"Expose a port or a range of ports\")\n\tflags.StringVar(&copts.ipv4Address, \"ip\", \"\", \"IPv4 address (e.g., 172.30.100.104)\")\n\tflags.StringVar(&copts.ipv6Address, \"ip6\", \"\", \"IPv6 address (e.g., 2001:db8::33)\")\n\tflags.Var(&copts.links, \"link\", \"Add link to another container\")\n\tflags.Var(&copts.linkLocalIPs, \"link-local-ip\", \"Container IPv4/IPv6 link-local addresses\")\n\tflags.StringVar(&copts.macAddress, \"mac-address\", \"\", \"Container MAC address (e.g., 92:d0:c6:0a:29:33)\")\n\tflags.VarP(&copts.publish, \"publish\", \"p\", \"Publish a container's port(s) to the host\")\n\tflags.BoolVarP(&copts.publishAll, \"publish-all\", \"P\", false, \"Publish all exposed ports to random ports\")\n\t// We allow for both \"--net\" and \"--network\", although the latter is the recommended way.\n\tflags.Var(&copts.netMode, \"net\", \"Connect a container to a network\")\n\tflags.Var(&copts.netMode, \"network\", \"Connect a container to a network\")\n\tflags.MarkHidden(\"net\")\n\t// We allow for both \"--net-alias\" and \"--network-alias\", although the latter is the recommended way.\n\tflags.Var(&copts.aliases, \"net-alias\", \"Add network-scoped alias for the container\")\n\tflags.Var(&copts.aliases, \"network-alias\", \"Add network-scoped alias for the container\")\n\tflags.MarkHidden(\"net-alias\")\n\n\t// Logging and storage\n\tflags.StringVar(&copts.loggingDriver, \"log-driver\", \"\", \"Logging driver for the container\")\n\tflags.StringVar(&copts.volumeDriver, \"volume-driver\", \"\", \"Optional volume driver for the container\")\n\tflags.Var(&copts.loggingOpts, \"log-opt\", \"Log driver options\")\n\tflags.Var(&copts.storageOpt, \"storage-opt\", \"Storage driver options for the container\")\n\tflags.Var(&copts.tmpfs, \"tmpfs\", \"Mount a tmpfs directory\")\n\tflags.Var(&copts.volumesFrom, \"volumes-from\", \"Mount volumes from the specified container(s)\")\n\tflags.VarP(&copts.volumes, \"volume\", \"v\", \"Bind mount a volume\")\n\tflags.Var(&copts.mounts, \"mount\", \"Attach a filesystem mount to the container\")\n\n\t// Health-checking\n\tflags.StringVar(&copts.healthCmd, \"health-cmd\", \"\", \"Command to run to check health\")\n\tflags.DurationVar(&copts.healthInterval, \"health-interval\", 0, \"Time between running the check (ms|s|m|h) (default 0s)\")\n\tflags.IntVar(&copts.healthRetries, \"health-retries\", 0, \"Consecutive failures needed to report unhealthy\")\n\tflags.DurationVar(&copts.healthTimeout, \"health-timeout\", 0, \"Maximum time to allow one check to run (ms|s|m|h) (default 0s)\")\n\tflags.DurationVar(&copts.healthStartPeriod, \"health-start-period\", 0, \"Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)\")\n\tflags.SetAnnotation(\"health-start-period\", \"version\", []string{\"1.29\"})\n\tflags.BoolVar(&copts.noHealthcheck, \"no-healthcheck\", false, \"Disable any container-specified HEALTHCHECK\")\n\n\t// Resource management\n\tflags.Uint16Var(&copts.blkioWeight, \"blkio-weight\", 0, \"Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)\")\n\tflags.Var(&copts.blkioWeightDevice, \"blkio-weight-device\", \"Block IO weight (relative device weight)\")\n\tflags.StringVar(&copts.containerIDFile, \"cidfile\", \"\", \"Write the container ID to the file\")\n\tflags.StringVar(&copts.cpusetCpus, \"cpuset-cpus\", \"\", \"CPUs in which to allow execution (0-3, 0,1)\")\n\tflags.StringVar(&copts.cpusetMems, \"cpuset-mems\", \"\", \"MEMs in which to allow execution (0-3, 0,1)\")\n\tflags.Int64Var(&copts.cpuCount, \"cpu-count\", 0, \"CPU count (Windows only)\")\n\tflags.SetAnnotation(\"cpu-count\", \"ostype\", []string{\"windows\"})\n\tflags.Int64Var(&copts.cpuPercent, \"cpu-percent\", 0, \"CPU percent (Windows only)\")\n\tflags.SetAnnotation(\"cpu-percent\", \"ostype\", []string{\"windows\"})\n\tflags.Int64Var(&copts.cpuPeriod, \"cpu-period\", 0, \"Limit CPU CFS (Completely Fair Scheduler) period\")\n\tflags.Int64Var(&copts.cpuQuota, \"cpu-quota\", 0, \"Limit CPU CFS (Completely Fair Scheduler) quota\")\n\tflags.Int64Var(&copts.cpuRealtimePeriod, \"cpu-rt-period\", 0, \"Limit CPU real-time period in microseconds\")\n\tflags.SetAnnotation(\"cpu-rt-period\", \"version\", []string{\"1.25\"})\n\tflags.Int64Var(&copts.cpuRealtimeRuntime, \"cpu-rt-runtime\", 0, \"Limit CPU real-time runtime in microseconds\")\n\tflags.SetAnnotation(\"cpu-rt-runtime\", \"version\", []string{\"1.25\"})\n\tflags.Int64VarP(&copts.cpuShares, \"cpu-shares\", \"c\", 0, \"CPU shares (relative weight)\")\n\tflags.Var(&copts.cpus, \"cpus\", \"Number of CPUs\")\n\tflags.SetAnnotation(\"cpus\", \"version\", []string{\"1.25\"})\n\tflags.Var(&copts.deviceReadBps, \"device-read-bps\", \"Limit read rate (bytes per second) from a device\")\n\tflags.Var(&copts.deviceReadIOps, \"device-read-iops\", \"Limit read rate (IO per second) from a device\")\n\tflags.Var(&copts.deviceWriteBps, \"device-write-bps\", \"Limit write rate (bytes per second) to a device\")\n\tflags.Var(&copts.deviceWriteIOps, \"device-write-iops\", \"Limit write rate (IO per second) to a device\")\n\tflags.Uint64Var(&copts.ioMaxBandwidth, \"io-maxbandwidth\", 0, \"Maximum IO bandwidth limit for the system drive (Windows only)\")\n\tflags.SetAnnotation(\"io-maxbandwidth\", \"ostype\", []string{\"windows\"})\n\tflags.Uint64Var(&copts.ioMaxIOps, \"io-maxiops\", 0, \"Maximum IOps limit for the system drive (Windows only)\")\n\tflags.SetAnnotation(\"io-maxiops\", \"ostype\", []string{\"windows\"})\n\tflags.Var(&copts.kernelMemory, \"kernel-memory\", \"Kernel memory limit\")\n\tflags.VarP(&copts.memory, \"memory\", \"m\", \"Memory limit\")\n\tflags.Var(&copts.memoryReservation, \"memory-reservation\", \"Memory soft limit\")\n\tflags.Var(&copts.memorySwap, \"memory-swap\", \"Swap limit equal to memory plus swap: '-1' to enable unlimited swap\")\n\tflags.Int64Var(&copts.swappiness, \"memory-swappiness\", -1, \"Tune container memory swappiness (0 to 100)\")\n\tflags.BoolVar(&copts.oomKillDisable, \"oom-kill-disable\", false, \"Disable OOM Killer\")\n\tflags.IntVar(&copts.oomScoreAdj, \"oom-score-adj\", 0, \"Tune host's OOM preferences (-1000 to 1000)\")\n\tflags.Int64Var(&copts.pidsLimit, \"pids-limit\", 0, \"Tune container pids limit (set -1 for unlimited)\")\n\n\t// Low-level execution (cgroups, namespaces, ...)\n\tflags.StringVar(&copts.cgroupParent, \"cgroup-parent\", \"\", \"Optional parent cgroup for the container\")\n\tflags.StringVar(&copts.ipcMode, \"ipc\", \"\", \"IPC mode to use\")\n\tflags.StringVar(&copts.isolation, \"isolation\", \"\", \"Container isolation technology\")\n\tflags.StringVar(&copts.pidMode, \"pid\", \"\", \"PID namespace to use\")\n\tflags.Var(&copts.shmSize, \"shm-size\", \"Size of /dev/shm\")\n\tflags.StringVar(&copts.utsMode, \"uts\", \"\", \"UTS namespace to use\")\n\tflags.StringVar(&copts.runtime, \"runtime\", \"\", \"Runtime to use for this container\")\n\n\tflags.BoolVar(&copts.init, \"init\", false, \"Run an init inside the container that forwards signals and reaps processes\")\n\tflags.SetAnnotation(\"init\", \"version\", []string{\"1.25\"})\n\treturn copts\n}\n\ntype containerConfig struct {\n\tConfig           *container.Config\n\tHostConfig       *container.HostConfig\n\tNetworkingConfig *networktypes.NetworkingConfig\n}\n\n// parse parses the args for the specified command and generates a Config,\n// a HostConfig and returns them with the specified command.\n// If the specified args are not valid, it will return an error.\n//\n//nolint:gocyclo\nfunc parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*containerConfig, error) {\n\tvar (\n\t\tattachStdin  = copts.attach.Get(\"stdin\")\n\t\tattachStdout = copts.attach.Get(\"stdout\")\n\t\tattachStderr = copts.attach.Get(\"stderr\")\n\t)\n\n\t// Validate the input mac address\n\tif copts.macAddress != \"\" {\n\t\tif _, err := opts.ValidateMACAddress(copts.macAddress); err != nil {\n\t\t\treturn nil, errors.Errorf(\"%s is not a valid mac address\", copts.macAddress)\n\t\t}\n\t}\n\tif copts.stdin {\n\t\tattachStdin = true\n\t}\n\t// If -a is not set, attach to stdout and stderr\n\tif copts.attach.Len() == 0 {\n\t\tattachStdout = true\n\t\tattachStderr = true\n\t}\n\n\tvar err error\n\n\tswappiness := copts.swappiness\n\tif swappiness != -1 && (swappiness < 0 || swappiness > 100) {\n\t\treturn nil, errors.Errorf(\"invalid value: %d. Valid memory swappiness range is 0-100\", swappiness)\n\t}\n\n\tmounts := copts.mounts.Value()\n\tif len(mounts) > 0 && copts.volumeDriver != \"\" {\n\t\tlogrus.Warn(\"`--volume-driver` is ignored for volumes specified via `--mount`. Use `--mount type=volume,volume-driver=...` instead.\")\n\t}\n\tvar binds []string\n\tvolumes := copts.volumes.GetMap()\n\t// add any bind targets to the list of container volumes\n\tfor bind := range copts.volumes.GetMap() {\n\t\tparsed, _ := loader.ParseVolume(bind)\n\n\t\tif parsed.Source != \"\" {\n\t\t\ttoBind := bind\n\n\t\t\tif parsed.Type == string(mounttypes.TypeBind) {\n\t\t\t\tif arr := strings.SplitN(bind, \":\", 2); len(arr) == 2 {\n\t\t\t\t\thostPart := arr[0]\n\t\t\t\t\tif strings.HasPrefix(hostPart, \".\"+string(filepath.Separator)) || hostPart == \".\" {\n\t\t\t\t\t\tif absHostPart, err := filepath.Abs(hostPart); err == nil {\n\t\t\t\t\t\t\thostPart = absHostPart\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ttoBind = hostPart + \":\" + arr[1]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// after creating the bind mount we want to delete it from the copts.volumes values because\n\t\t\t// we do not want bind mounts being committed to image configs\n\t\t\tbinds = append(binds, toBind)\n\t\t\t// We should delete from the map (`volumes`) here, as deleting from copts.volumes will not work if\n\t\t\t// there are duplicates entries.\n\t\t\tdelete(volumes, bind)\n\t\t}\n\t}\n\n\t// Can't evaluate options passed into --tmpfs until we actually mount\n\ttmpfs := make(map[string]string)\n\tfor _, t := range copts.tmpfs.GetSlice() {\n\t\tif arr := strings.SplitN(t, \":\", 2); len(arr) > 1 {\n\t\t\ttmpfs[arr[0]] = arr[1]\n\t\t} else {\n\t\t\ttmpfs[arr[0]] = \"\"\n\t\t}\n\t}\n\n\tvar (\n\t\trunCmd     strslice.StrSlice\n\t\tentrypoint strslice.StrSlice\n\t)\n\n\tif len(copts.Args) > 0 {\n\t\trunCmd = strslice.StrSlice(copts.Args)\n\t}\n\n\tif copts.entrypoint != \"\" {\n\t\tentrypoint = strslice.StrSlice{copts.entrypoint}\n\t} else if flags.Changed(\"entrypoint\") {\n\t\t// if `--entrypoint=` is parsed then Entrypoint is reset\n\t\tentrypoint = []string{\"\"}\n\t}\n\n\tpublishOpts := copts.publish.GetSlice()\n\tvar (\n\t\tports         map[nat.Port]struct{}\n\t\tportBindings  map[nat.Port][]nat.PortBinding\n\t\tconvertedOpts []string\n\t)\n\n\tconvertedOpts, err = convertToStandardNotation(publishOpts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tports, portBindings, err = nat.ParsePortSpecs(convertedOpts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Merge in exposed ports to the map of published ports\n\tfor _, e := range copts.expose.GetSlice() {\n\t\tif strings.Contains(e, \":\") {\n\t\t\treturn nil, errors.Errorf(\"invalid port format for --expose: %s\", e)\n\t\t}\n\t\t// support two formats for expose, original format <portnum>/[<proto>]\n\t\t// or <startport-endport>/[<proto>]\n\t\tproto, port := nat.SplitProtoPort(e)\n\t\t// parse the start and end port and create a sequence of ports to expose\n\t\t// if expose a port, the start and end port are the same\n\t\tstart, end, err := nat.ParsePortRange(port)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Errorf(\"invalid range format for --expose: %s, error: %s\", e, err)\n\t\t}\n\t\tfor i := start; i <= end; i++ {\n\t\t\tp, err := nat.NewPort(proto, strconv.FormatUint(i, 10))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif _, exists := ports[p]; !exists {\n\t\t\t\tports[p] = struct{}{}\n\t\t\t}\n\t\t}\n\t}\n\n\t// validate and parse device mappings. Note we do late validation of the\n\t// device path (as opposed to during flag parsing), as at the time we are\n\t// parsing flags, we haven't yet sent a _ping to the daemon to determine\n\t// what operating system it is.\n\tdeviceMappings := []container.DeviceMapping{}\n\tfor _, device := range copts.devices.GetSlice() {\n\t\tvar (\n\t\t\tvalidated     string\n\t\t\tdeviceMapping container.DeviceMapping\n\t\t\terr           error\n\t\t)\n\t\tvalidated, err = validateDevice(device, serverOS)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdeviceMapping, err = parseDevice(validated, serverOS)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdeviceMappings = append(deviceMappings, deviceMapping)\n\t}\n\n\t// collect all the environment variables for the container\n\tenvVariables, err := opts.ReadKVEnvStrings(copts.envFile.GetSlice(), copts.env.GetSlice())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// collect all the labels for the container\n\tlabels, err := opts.ReadKVStrings(copts.labelsFile.GetSlice(), copts.labels.GetSlice())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpidMode := container.PidMode(copts.pidMode)\n\tif !pidMode.Valid() {\n\t\treturn nil, errors.Errorf(\"--pid: invalid PID mode\")\n\t}\n\n\tutsMode := container.UTSMode(copts.utsMode)\n\tif !utsMode.Valid() {\n\t\treturn nil, errors.Errorf(\"--uts: invalid UTS mode\")\n\t}\n\n\tusernsMode := container.UsernsMode(copts.usernsMode)\n\tif !usernsMode.Valid() {\n\t\treturn nil, errors.Errorf(\"--userns: invalid USER mode\")\n\t}\n\n\tcgroupnsMode := container.CgroupnsMode(copts.cgroupnsMode)\n\tif !cgroupnsMode.Valid() {\n\t\treturn nil, errors.Errorf(\"--cgroupns: invalid CGROUP mode\")\n\t}\n\n\trestartPolicy, err := opts.ParseRestartPolicy(copts.restartPolicy)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tloggingOpts, err := parseLoggingOpts(copts.loggingDriver, copts.loggingOpts.GetSlice())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsecurityOpts, err := parseSecurityOpts(copts.securityOpt.GetSlice())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsecurityOpts, maskedPaths, readonlyPaths := parseSystemPaths(securityOpts)\n\n\tstorageOpts, err := parseStorageOpts(copts.storageOpt.GetSlice())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Healthcheck\n\tvar healthConfig *container.HealthConfig\n\thaveHealthSettings := copts.healthCmd != \"\" ||\n\t\tcopts.healthInterval != 0 ||\n\t\tcopts.healthTimeout != 0 ||\n\t\tcopts.healthStartPeriod != 0 ||\n\t\tcopts.healthRetries != 0\n\tif copts.noHealthcheck {\n\t\tif haveHealthSettings {\n\t\t\treturn nil, errors.Errorf(\"--no-healthcheck conflicts with --health-* options\")\n\t\t}\n\t\ttest := strslice.StrSlice{\"NONE\"}\n\t\thealthConfig = &container.HealthConfig{Test: test}\n\t} else if haveHealthSettings {\n\t\tvar probe strslice.StrSlice\n\t\tif copts.healthCmd != \"\" {\n\t\t\targs := []string{\"CMD-SHELL\", copts.healthCmd}\n\t\t\tprobe = strslice.StrSlice(args)\n\t\t}\n\t\tif copts.healthInterval < 0 {\n\t\t\treturn nil, errors.Errorf(\"--health-interval cannot be negative\")\n\t\t}\n\t\tif copts.healthTimeout < 0 {\n\t\t\treturn nil, errors.Errorf(\"--health-timeout cannot be negative\")\n\t\t}\n\t\tif copts.healthRetries < 0 {\n\t\t\treturn nil, errors.Errorf(\"--health-retries cannot be negative\")\n\t\t}\n\t\tif copts.healthStartPeriod < 0 {\n\t\t\treturn nil, fmt.Errorf(\"--health-start-period cannot be negative\")\n\t\t}\n\n\t\thealthConfig = &container.HealthConfig{\n\t\t\tTest:        probe,\n\t\t\tInterval:    copts.healthInterval,\n\t\t\tTimeout:     copts.healthTimeout,\n\t\t\tStartPeriod: copts.healthStartPeriod,\n\t\t\tRetries:     copts.healthRetries,\n\t\t}\n\t}\n\n\tresources := container.Resources{\n\t\tCgroupParent:         copts.cgroupParent,\n\t\tMemory:               copts.memory.Value(),\n\t\tMemoryReservation:    copts.memoryReservation.Value(),\n\t\tMemorySwap:           copts.memorySwap.Value(),\n\t\tMemorySwappiness:     &copts.swappiness,\n\t\tKernelMemory:         copts.kernelMemory.Value(),\n\t\tOomKillDisable:       &copts.oomKillDisable,\n\t\tNanoCPUs:             copts.cpus.Value(),\n\t\tCPUCount:             copts.cpuCount,\n\t\tCPUPercent:           copts.cpuPercent,\n\t\tCPUShares:            copts.cpuShares,\n\t\tCPUPeriod:            copts.cpuPeriod,\n\t\tCpusetCpus:           copts.cpusetCpus,\n\t\tCpusetMems:           copts.cpusetMems,\n\t\tCPUQuota:             copts.cpuQuota,\n\t\tCPURealtimePeriod:    copts.cpuRealtimePeriod,\n\t\tCPURealtimeRuntime:   copts.cpuRealtimeRuntime,\n\t\tPidsLimit:            &copts.pidsLimit,\n\t\tBlkioWeight:          copts.blkioWeight,\n\t\tBlkioWeightDevice:    copts.blkioWeightDevice.GetList(),\n\t\tBlkioDeviceReadBps:   copts.deviceReadBps.GetList(),\n\t\tBlkioDeviceWriteBps:  copts.deviceWriteBps.GetList(),\n\t\tBlkioDeviceReadIOps:  copts.deviceReadIOps.GetList(),\n\t\tBlkioDeviceWriteIOps: copts.deviceWriteIOps.GetList(),\n\t\tIOMaximumIOps:        copts.ioMaxIOps,\n\t\tIOMaximumBandwidth:   copts.ioMaxBandwidth,\n\t\tUlimits:              copts.ulimits.GetList(),\n\t\tDeviceCgroupRules:    copts.deviceCgroupRules.GetSlice(),\n\t\tDevices:              deviceMappings,\n\t\tDeviceRequests:       copts.gpus.Value(),\n\t}\n\n\tconfig := &container.Config{\n\t\tHostname:     copts.hostname,\n\t\tDomainname:   copts.domainname,\n\t\tExposedPorts: ports,\n\t\tUser:         copts.user,\n\t\tTty:          copts.tty,\n\t\t// TODO: deprecated, it comes from -n, --networking\n\t\t// it's still needed internally to set the network to disabled\n\t\t// if e.g. bridge is none in daemon opts, and in inspect\n\t\tNetworkDisabled: false,\n\t\tOpenStdin:       copts.stdin,\n\t\tAttachStdin:     attachStdin,\n\t\tAttachStdout:    attachStdout,\n\t\tAttachStderr:    attachStderr,\n\t\tEnv:             envVariables,\n\t\tCmd:             runCmd,\n\t\tImage:           copts.Image,\n\t\tVolumes:         volumes,\n\t\tMacAddress:      copts.macAddress,\n\t\tEntrypoint:      entrypoint,\n\t\tWorkingDir:      copts.workingDir,\n\t\tLabels:          opts.ConvertKVStringsToMap(labels),\n\t\tStopSignal:      copts.stopSignal,\n\t\tHealthcheck:     healthConfig,\n\t}\n\tif flags.Changed(\"stop-timeout\") {\n\t\tconfig.StopTimeout = &copts.stopTimeout\n\t}\n\n\thostConfig := &container.HostConfig{\n\t\tBinds:           binds,\n\t\tContainerIDFile: copts.containerIDFile,\n\t\tOomScoreAdj:     copts.oomScoreAdj,\n\t\tAutoRemove:      copts.autoRemove,\n\t\tPrivileged:      copts.privileged,\n\t\tPortBindings:    portBindings,\n\t\tLinks:           copts.links.GetSlice(),\n\t\tPublishAllPorts: copts.publishAll,\n\t\t// Make sure the dns fields are never nil.\n\t\t// New containers don't ever have those fields nil,\n\t\t// but pre created containers can still have those nil values.\n\t\t// See https://github.com/docker/docker/pull/17779\n\t\t// for a more detailed explanation on why we don't want that.\n\t\tDNS:            copts.dns.GetAllOrEmpty(),\n\t\tDNSSearch:      copts.dnsSearch.GetAllOrEmpty(),\n\t\tDNSOptions:     copts.dnsOptions.GetAllOrEmpty(),\n\t\tExtraHosts:     copts.extraHosts.GetSlice(),\n\t\tVolumesFrom:    copts.volumesFrom.GetSlice(),\n\t\tIpcMode:        container.IpcMode(copts.ipcMode),\n\t\tNetworkMode:    container.NetworkMode(copts.netMode.NetworkMode()),\n\t\tPidMode:        pidMode,\n\t\tUTSMode:        utsMode,\n\t\tUsernsMode:     usernsMode,\n\t\tCgroupnsMode:   cgroupnsMode,\n\t\tCapAdd:         strslice.StrSlice(copts.capAdd.GetSlice()),\n\t\tCapDrop:        strslice.StrSlice(copts.capDrop.GetSlice()),\n\t\tGroupAdd:       copts.groupAdd.GetSlice(),\n\t\tRestartPolicy:  restartPolicy,\n\t\tSecurityOpt:    securityOpts,\n\t\tStorageOpt:     storageOpts,\n\t\tReadonlyRootfs: copts.readonlyRootfs,\n\t\tLogConfig:      container.LogConfig{Type: copts.loggingDriver, Config: loggingOpts},\n\t\tVolumeDriver:   copts.volumeDriver,\n\t\tIsolation:      container.Isolation(copts.isolation),\n\t\tShmSize:        copts.shmSize.Value(),\n\t\tResources:      resources,\n\t\tTmpfs:          tmpfs,\n\t\tSysctls:        copts.sysctls.GetAll(),\n\t\tRuntime:        copts.runtime,\n\t\tMounts:         mounts,\n\t\tMaskedPaths:    maskedPaths,\n\t\tReadonlyPaths:  readonlyPaths,\n\t}\n\n\tif copts.autoRemove && !hostConfig.RestartPolicy.IsNone() {\n\t\treturn nil, errors.Errorf(\"Conflicting options: --restart and --rm\")\n\t}\n\n\t// only set this value if the user provided the flag, else it should default to nil\n\tif flags.Changed(\"init\") {\n\t\thostConfig.Init = &copts.init\n\t}\n\n\t// When allocating stdin in attached mode, close stdin at client disconnect\n\tif config.OpenStdin && config.AttachStdin {\n\t\tconfig.StdinOnce = true\n\t}\n\n\tnetworkingConfig := &networktypes.NetworkingConfig{\n\t\tEndpointsConfig: make(map[string]*networktypes.EndpointSettings),\n\t}\n\n\tnetworkingConfig.EndpointsConfig, err = parseNetworkOpts(copts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &containerConfig{\n\t\tConfig:           config,\n\t\tHostConfig:       hostConfig,\n\t\tNetworkingConfig: networkingConfig,\n\t}, nil\n}\n\n// parseNetworkOpts converts --network advanced options to endpoint-specs, and combines\n// them with the old --network-alias and --links. If returns an error if conflicting options\n// are found.\n//\n// this function may return _multiple_ endpoints, which is not currently supported\n// by the daemon, but may be in future; it's up to the daemon to produce an error\n// in case that is not supported.\nfunc parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.EndpointSettings, error) {\n\tvar (\n\t\tendpoints                         = make(map[string]*networktypes.EndpointSettings, len(copts.netMode.Value()))\n\t\thasUserDefined, hasNonUserDefined bool\n\t)\n\n\tfor i, n := range copts.netMode.Value() {\n\t\tif container.NetworkMode(n.Target).IsUserDefined() {\n\t\t\thasUserDefined = true\n\t\t} else {\n\t\t\thasNonUserDefined = true\n\t\t}\n\t\tif i == 0 {\n\t\t\t// The first network corresponds with what was previously the \"only\"\n\t\t\t// network, and what would be used when using the non-advanced syntax\n\t\t\t// `--network-alias`, `--link`, `--ip`, `--ip6`, and `--link-local-ip`\n\t\t\t// are set on this network, to preserve backward compatibility with\n\t\t\t// the non-advanced notation\n\t\t\tif err := applyContainerOptions(&n, copts); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tep, err := parseNetworkAttachmentOpt(n)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif _, ok := endpoints[n.Target]; ok {\n\t\t\treturn nil, errdefs.InvalidParameter(errors.Errorf(\"network %q is specified multiple times\", n.Target))\n\t\t}\n\n\t\t// For backward compatibility: if no custom options are provided for the network,\n\t\t// and only a single network is specified, omit the endpoint-configuration\n\t\t// on the client (the daemon will still create it when creating the container)\n\t\tif i == 0 && len(copts.netMode.Value()) == 1 {\n\t\t\tif ep == nil || reflect.DeepEqual(*ep, networktypes.EndpointSettings{}) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tendpoints[n.Target] = ep\n\t}\n\tif hasUserDefined && hasNonUserDefined {\n\t\treturn nil, errdefs.InvalidParameter(errors.New(\"conflicting options: cannot attach both user-defined and non-user-defined network-modes\"))\n\t}\n\treturn endpoints, nil\n}\n\nfunc applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *containerOptions) error {\n\t// TODO should copts.MacAddress actually be set on the first network? (currently it's not)\n\t// TODO should we error if _any_ advanced option is used? (i.e. forbid to combine advanced notation with the \"old\" flags (`--network-alias`, `--link`, `--ip`, `--ip6`)?\n\tif len(n.Aliases) > 0 && copts.aliases.Len() > 0 {\n\t\treturn errdefs.InvalidParameter(errors.New(\"conflicting options: cannot specify both --network-alias and per-network alias\"))\n\t}\n\tif len(n.Links) > 0 && copts.links.Len() > 0 {\n\t\treturn errdefs.InvalidParameter(errors.New(\"conflicting options: cannot specify both --link and per-network links\"))\n\t}\n\tif n.IPv4Address != \"\" && copts.ipv4Address != \"\" {\n\t\treturn errdefs.InvalidParameter(errors.New(\"conflicting options: cannot specify both --ip and per-network IPv4 address\"))\n\t}\n\tif n.IPv6Address != \"\" && copts.ipv6Address != \"\" {\n\t\treturn errdefs.InvalidParameter(errors.New(\"conflicting options: cannot specify both --ip6 and per-network IPv6 address\"))\n\t}\n\tif copts.aliases.Len() > 0 {\n\t\tn.Aliases = make([]string, copts.aliases.Len())\n\t\tcopy(n.Aliases, copts.aliases.GetSlice())\n\t}\n\tif copts.links.Len() > 0 {\n\t\tn.Links = make([]string, copts.links.Len())\n\t\tcopy(n.Links, copts.links.GetSlice())\n\t}\n\tif copts.ipv4Address != \"\" {\n\t\tn.IPv4Address = copts.ipv4Address\n\t}\n\tif copts.ipv6Address != \"\" {\n\t\tn.IPv6Address = copts.ipv6Address\n\t}\n\n\t// TODO should linkLocalIPs be added to the _first_ network only, or to _all_ networks? (should this be a per-network option as well?)\n\tif copts.linkLocalIPs.Len() > 0 {\n\t\tn.LinkLocalIPs = make([]string, copts.linkLocalIPs.Len())\n\t\tcopy(n.LinkLocalIPs, copts.linkLocalIPs.GetSlice())\n\t}\n\treturn nil\n}\n\nfunc parseNetworkAttachmentOpt(ep opts.NetworkAttachmentOpts) (*networktypes.EndpointSettings, error) {\n\tif strings.TrimSpace(ep.Target) == \"\" {\n\t\treturn nil, errors.New(\"no name set for network\")\n\t}\n\tif !container.NetworkMode(ep.Target).IsUserDefined() {\n\t\tif len(ep.Aliases) > 0 {\n\t\t\treturn nil, errors.New(\"network-scoped aliases are only supported for user-defined networks\")\n\t\t}\n\t\tif len(ep.Links) > 0 {\n\t\t\treturn nil, errors.New(\"links are only supported for user-defined networks\")\n\t\t}\n\t}\n\n\tepConfig := &networktypes.EndpointSettings{}\n\tepConfig.Aliases = append(epConfig.Aliases, ep.Aliases...)\n\tif len(ep.DriverOpts) > 0 {\n\t\tepConfig.DriverOpts = make(map[string]string)\n\t\tepConfig.DriverOpts = ep.DriverOpts\n\t}\n\tif len(ep.Links) > 0 {\n\t\tepConfig.Links = ep.Links\n\t}\n\tif ep.IPv4Address != \"\" || ep.IPv6Address != \"\" || len(ep.LinkLocalIPs) > 0 {\n\t\tepConfig.IPAMConfig = &networktypes.EndpointIPAMConfig{\n\t\t\tIPv4Address:  ep.IPv4Address,\n\t\t\tIPv6Address:  ep.IPv6Address,\n\t\t\tLinkLocalIPs: ep.LinkLocalIPs,\n\t\t}\n\t}\n\treturn epConfig, nil\n}\n\nfunc convertToStandardNotation(ports []string) ([]string, error) {\n\toptsList := []string{}\n\tfor _, publish := range ports {\n\t\tif strings.Contains(publish, \"=\") {\n\t\t\tparams := map[string]string{\"protocol\": \"tcp\"}\n\t\t\tfor _, param := range strings.Split(publish, \",\") {\n\t\t\t\topt := strings.Split(param, \"=\")\n\t\t\t\tif len(opt) < 2 {\n\t\t\t\t\treturn optsList, errors.Errorf(\"invalid publish opts format (should be name=value but got '%s')\", param)\n\t\t\t\t}\n\n\t\t\t\tparams[opt[0]] = opt[1]\n\t\t\t}\n\t\t\toptsList = append(optsList, fmt.Sprintf(\"%s:%s/%s\", params[\"published\"], params[\"target\"], params[\"protocol\"]))\n\t\t} else {\n\t\t\toptsList = append(optsList, publish)\n\t\t}\n\t}\n\treturn optsList, nil\n}\n\nfunc parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {\n\tloggingOptsMap := opts.ConvertKVStringsToMap(loggingOpts)\n\tif loggingDriver == \"none\" && len(loggingOpts) > 0 {\n\t\treturn map[string]string{}, errors.Errorf(\"invalid logging opts for driver %s\", loggingDriver)\n\t}\n\treturn loggingOptsMap, nil\n}\n\n// takes a local seccomp daemon, reads the file contents for sending to the daemon\nfunc parseSecurityOpts(securityOpts []string) ([]string, error) {\n\tfor key, opt := range securityOpts {\n\t\tcon := strings.SplitN(opt, \"=\", 2)\n\t\tif len(con) == 1 && con[0] != \"no-new-privileges\" {\n\t\t\tif strings.Contains(opt, \":\") {\n\t\t\t\tcon = strings.SplitN(opt, \":\", 2)\n\t\t\t} else {\n\t\t\t\treturn securityOpts, errors.Errorf(\"Invalid --security-opt: %q\", opt)\n\t\t\t}\n\t\t}\n\t\tif con[0] == \"seccomp\" && con[1] != \"unconfined\" {\n\t\t\tf, err := os.ReadFile(con[1])\n\t\t\tif err != nil {\n\t\t\t\treturn securityOpts, errors.Errorf(\"opening seccomp profile (%s) failed: %v\", con[1], err)\n\t\t\t}\n\t\t\tb := bytes.NewBuffer(nil)\n\t\t\tif err := json.Compact(b, f); err != nil {\n\t\t\t\treturn securityOpts, errors.Errorf(\"compacting json for seccomp profile (%s) failed: %v\", con[1], err)\n\t\t\t}\n\t\t\tsecurityOpts[key] = fmt.Sprintf(\"seccomp=%s\", b.Bytes())\n\t\t}\n\t}\n\n\treturn securityOpts, nil\n}\n\n// parseSystemPaths checks if `systempaths=unconfined` security option is set,\n// and returns the `MaskedPaths` and `ReadonlyPaths` accordingly. An updated\n// list of security options is returned with this option removed, because the\n// `unconfined` option is handled client-side, and should not be sent to the\n// daemon.\nfunc parseSystemPaths(securityOpts []string) (filtered, maskedPaths, readonlyPaths []string) {\n\tfiltered = securityOpts[:0]\n\tfor _, opt := range securityOpts {\n\t\tif opt == \"systempaths=unconfined\" {\n\t\t\tmaskedPaths = []string{}\n\t\t\treadonlyPaths = []string{}\n\t\t} else {\n\t\t\tfiltered = append(filtered, opt)\n\t\t}\n\t}\n\n\treturn filtered, maskedPaths, readonlyPaths\n}\n\n// parses storage options per container into a map\nfunc parseStorageOpts(storageOpts []string) (map[string]string, error) {\n\tm := make(map[string]string)\n\tfor _, option := range storageOpts {\n\t\tif strings.Contains(option, \"=\") {\n\t\t\topt := strings.SplitN(option, \"=\", 2)\n\t\t\tm[opt[0]] = opt[1]\n\t\t} else {\n\t\t\treturn nil, errors.Errorf(\"invalid storage option\")\n\t\t}\n\t}\n\treturn m, nil\n}\n\n// parseDevice parses a device mapping string to a container.DeviceMapping struct\nfunc parseDevice(device, serverOS string) (container.DeviceMapping, error) {\n\tswitch serverOS {\n\tcase \"linux\":\n\t\treturn parseLinuxDevice(device)\n\tcase \"windows\":\n\t\treturn parseWindowsDevice(device)\n\t}\n\treturn container.DeviceMapping{}, errors.Errorf(\"unknown server OS: %s\", serverOS)\n}\n\n// parseLinuxDevice parses a device mapping string to a container.DeviceMapping struct\n// knowing that the target is a Linux daemon\nfunc parseLinuxDevice(device string) (container.DeviceMapping, error) {\n\tvar src, dst string\n\tpermissions := \"rwm\"\n\tarr := strings.Split(device, \":\")\n\tswitch len(arr) {\n\tcase 3:\n\t\tpermissions = arr[2]\n\t\tfallthrough\n\tcase 2:\n\t\tif validDeviceMode(arr[1]) {\n\t\t\tpermissions = arr[1]\n\t\t} else {\n\t\t\tdst = arr[1]\n\t\t}\n\t\tfallthrough\n\tcase 1:\n\t\tsrc = arr[0]\n\tdefault:\n\t\treturn container.DeviceMapping{}, errors.Errorf(\"invalid device specification: %s\", device)\n\t}\n\n\tif dst == \"\" {\n\t\tdst = src\n\t}\n\n\tdeviceMapping := container.DeviceMapping{\n\t\tPathOnHost:        src,\n\t\tPathInContainer:   dst,\n\t\tCgroupPermissions: permissions,\n\t}\n\treturn deviceMapping, nil\n}\n\n// parseWindowsDevice parses a device mapping string to a container.DeviceMapping struct\n// knowing that the target is a Windows daemon\nfunc parseWindowsDevice(device string) (container.DeviceMapping, error) {\n\treturn container.DeviceMapping{PathOnHost: device}, nil\n}\n\n// validateDeviceCgroupRule validates a device cgroup rule string format\n// It will make sure 'val' is in the form:\n//\n//\t'type major:minor mode'\nfunc validateDeviceCgroupRule(val string) (string, error) {\n\tif deviceCgroupRuleRegexp.MatchString(val) {\n\t\treturn val, nil\n\t}\n\n\treturn val, errors.Errorf(\"invalid device cgroup format '%s'\", val)\n}\n\n// validDeviceMode checks if the mode for device is valid or not.\n// Valid mode is a composition of r (read), w (write), and m (mknod).\nfunc validDeviceMode(mode string) bool {\n\tvar legalDeviceMode = map[rune]bool{\n\t\t'r': true,\n\t\t'w': true,\n\t\t'm': true,\n\t}\n\tif mode == \"\" {\n\t\treturn false\n\t}\n\tfor _, c := range mode {\n\t\tif !legalDeviceMode[c] {\n\t\t\treturn false\n\t\t}\n\t\tlegalDeviceMode[c] = false\n\t}\n\treturn true\n}\n\n// validateDevice validates a path for devices\nfunc validateDevice(val string, serverOS string) (string, error) {\n\tswitch serverOS {\n\tcase \"linux\":\n\t\treturn validateLinuxPath(val, validDeviceMode)\n\tcase \"windows\":\n\t\t// Windows does validation entirely server-side\n\t\treturn val, nil\n\t}\n\treturn \"\", errors.Errorf(\"unknown server OS: %s\", serverOS)\n}\n\n// validateLinuxPath is the implementation of validateDevice knowing that the\n// target server operating system is a Linux daemon.\n// It will make sure 'val' is in the form:\n//\n//\t[host-dir:]container-path[:mode]\n//\n// It also validates the device mode.\nfunc validateLinuxPath(val string, validator func(string) bool) (string, error) {\n\tvar containerPath string\n\tvar mode string\n\n\tif strings.Count(val, \":\") > 2 {\n\t\treturn val, errors.Errorf(\"bad format for path: %s\", val)\n\t}\n\n\tsplit := strings.SplitN(val, \":\", 3)\n\tif split[0] == \"\" {\n\t\treturn val, errors.Errorf(\"bad format for path: %s\", val)\n\t}\n\tswitch len(split) {\n\tcase 1:\n\t\tcontainerPath = split[0]\n\t\tval = path.Clean(containerPath)\n\tcase 2:\n\t\tif isValid := validator(split[1]); isValid {\n\t\t\tcontainerPath = split[0]\n\t\t\tmode = split[1]\n\t\t\tval = fmt.Sprintf(\"%s:%s\", path.Clean(containerPath), mode)\n\t\t} else {\n\t\t\tcontainerPath = split[1]\n\t\t\tval = fmt.Sprintf(\"%s:%s\", split[0], path.Clean(containerPath))\n\t\t}\n\tcase 3:\n\t\tcontainerPath = split[1]\n\t\tmode = split[2]\n\t\tif isValid := validator(split[2]); !isValid {\n\t\t\treturn val, errors.Errorf(\"bad mode specified: %s\", mode)\n\t\t}\n\t\tval = fmt.Sprintf(\"%s:%s:%s\", split[0], containerPath, mode)\n\t}\n\n\tif !path.IsAbs(containerPath) {\n\t\treturn val, errors.Errorf(\"%s is not an absolute path\", containerPath)\n\t}\n\treturn val, nil\n}\n\n// validateAttach validates that the specified string is a valid attach option.\nfunc validateAttach(val string) (string, error) {\n\ts := strings.ToLower(val)\n\tfor _, str := range []string{\"stdin\", \"stdout\", \"stderr\"} {\n\t\tif s == str {\n\t\t\treturn s, nil\n\t\t}\n\t}\n\treturn val, errors.Errorf(\"valid streams are STDIN, STDOUT and STDERR\")\n}\n\nfunc validateAPIVersion(c *containerConfig, serverAPIVersion string) error {\n\tfor _, m := range c.HostConfig.Mounts {\n\t\tif m.BindOptions != nil && m.BindOptions.NonRecursive && versions.LessThan(serverAPIVersion, \"1.40\") {\n\t\t\treturn errors.Errorf(\"bind-nonrecursive requires API v1.40 or later\")\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/container/docker_cli_test.go",
    "content": "// This file is exact copy of https://github.com/docker/cli/blob/9ac8584acfd501c3f4da0e845e3a40ed15c85041/cli/command/container/opts_test.go with:\n// * appended with license information\n// * commented out case 'invalid-mixed-network-types' in test TestParseNetworkConfig\n//\n// docker/cli is licensed under the Apache License, Version 2.0.\n// See DOCKER_LICENSE for the full license text.\n//\n\n//nolint:unparam,whitespace,depguard,dupl,gocritic\npackage container\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\tnetworktypes \"github.com/docker/docker/api/types/network\"\n\t\"github.com/docker/go-connections/nat\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/spf13/pflag\"\n\t\"gotest.tools/v3/assert\"\n\tis \"gotest.tools/v3/assert/cmp\"\n\t\"gotest.tools/v3/skip\"\n)\n\nfunc TestValidateAttach(t *testing.T) {\n\tvalid := []string{\n\t\t\"stdin\",\n\t\t\"stdout\",\n\t\t\"stderr\",\n\t\t\"STDIN\",\n\t\t\"STDOUT\",\n\t\t\"STDERR\",\n\t}\n\tif _, err := validateAttach(\"invalid\"); err == nil {\n\t\tt.Fatal(\"Expected error with [valid streams are STDIN, STDOUT and STDERR], got nothing\")\n\t}\n\n\tfor _, attach := range valid {\n\t\tvalue, err := validateAttach(attach)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif value != strings.ToLower(attach) {\n\t\t\tt.Fatalf(\"Expected [%v], got [%v]\", attach, value)\n\t\t}\n\t}\n}\n\nfunc parseRun(args []string) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {\n\tflags, copts := setupRunFlags()\n\tif err := flags.Parse(args); err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\t// TODO: fix tests to accept ContainerConfig\n\tcontainerConfig, err := parse(flags, copts, runtime.GOOS)\n\tif err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\treturn containerConfig.Config, containerConfig.HostConfig, containerConfig.NetworkingConfig, err\n}\n\nfunc setupRunFlags() (*pflag.FlagSet, *containerOptions) {\n\tflags := pflag.NewFlagSet(\"run\", pflag.ContinueOnError)\n\tflags.SetOutput(io.Discard)\n\tflags.Usage = nil\n\tcopts := addFlags(flags)\n\treturn flags, copts\n}\n\nfunc mustParse(t *testing.T, args string) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig) {\n\tt.Helper()\n\tconfig, hostConfig, networkingConfig, err := parseRun(append(strings.Split(args, \" \"), \"ubuntu\", \"bash\"))\n\tassert.NilError(t, err)\n\treturn config, hostConfig, networkingConfig\n}\n\nfunc TestParseRunLinks(t *testing.T) {\n\tif _, hostConfig, _ := mustParse(t, \"--link a:b\"); len(hostConfig.Links) == 0 || hostConfig.Links[0] != \"a:b\" {\n\t\tt.Fatalf(\"Error parsing links. Expected []string{\\\"a:b\\\"}, received: %v\", hostConfig.Links)\n\t}\n\tif _, hostConfig, _ := mustParse(t, \"--link a:b --link c:d\"); len(hostConfig.Links) < 2 || hostConfig.Links[0] != \"a:b\" || hostConfig.Links[1] != \"c:d\" {\n\t\tt.Fatalf(\"Error parsing links. Expected []string{\\\"a:b\\\", \\\"c:d\\\"}, received: %v\", hostConfig.Links)\n\t}\n\tif _, hostConfig, _ := mustParse(t, \"\"); len(hostConfig.Links) != 0 {\n\t\tt.Fatalf(\"Error parsing links. No link expected, received: %v\", hostConfig.Links)\n\t}\n}\n\nfunc TestParseRunAttach(t *testing.T) {\n\ttests := []struct {\n\t\tinput    string\n\t\texpected container.Config\n\t}{\n\t\t{\n\t\t\tinput: \"\",\n\t\t\texpected: container.Config{\n\t\t\t\tAttachStdout: true,\n\t\t\t\tAttachStderr: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput: \"-i\",\n\t\t\texpected: container.Config{\n\t\t\t\tAttachStdin:  true,\n\t\t\t\tAttachStdout: true,\n\t\t\t\tAttachStderr: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput: \"-a stdin\",\n\t\t\texpected: container.Config{\n\t\t\t\tAttachStdin: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput: \"-a stdin -a stdout\",\n\t\t\texpected: container.Config{\n\t\t\t\tAttachStdin:  true,\n\t\t\t\tAttachStdout: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput: \"-a stdin -a stdout -a stderr\",\n\t\t\texpected: container.Config{\n\t\t\t\tAttachStdin:  true,\n\t\t\t\tAttachStdout: true,\n\t\t\t\tAttachStderr: true,\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tc := range tests {\n\t\tt.Run(tc.input, func(t *testing.T) {\n\t\t\tconfig, _, _ := mustParse(t, tc.input)\n\t\t\tassert.Equal(t, config.AttachStdin, tc.expected.AttachStdin)\n\t\t\tassert.Equal(t, config.AttachStdout, tc.expected.AttachStdout)\n\t\t\tassert.Equal(t, config.AttachStderr, tc.expected.AttachStderr)\n\t\t})\n\t}\n}\n\nfunc TestParseRunWithInvalidArgs(t *testing.T) {\n\ttests := []struct {\n\t\targs  []string\n\t\terror string\n\t}{\n\t\t{\n\t\t\targs:  []string{\"-a\", \"ubuntu\", \"bash\"},\n\t\t\terror: `invalid argument \"ubuntu\" for \"-a, --attach\" flag: valid streams are STDIN, STDOUT and STDERR`,\n\t\t},\n\t\t{\n\t\t\targs:  []string{\"-a\", \"invalid\", \"ubuntu\", \"bash\"},\n\t\t\terror: `invalid argument \"invalid\" for \"-a, --attach\" flag: valid streams are STDIN, STDOUT and STDERR`,\n\t\t},\n\t\t{\n\t\t\targs:  []string{\"-a\", \"invalid\", \"-a\", \"stdout\", \"ubuntu\", \"bash\"},\n\t\t\terror: `invalid argument \"invalid\" for \"-a, --attach\" flag: valid streams are STDIN, STDOUT and STDERR`,\n\t\t},\n\t\t{\n\t\t\targs:  []string{\"-a\", \"stdout\", \"-a\", \"stderr\", \"-z\", \"ubuntu\", \"bash\"},\n\t\t\terror: `unknown shorthand flag: 'z' in -z`,\n\t\t},\n\t\t{\n\t\t\targs:  []string{\"-a\", \"stdin\", \"-z\", \"ubuntu\", \"bash\"},\n\t\t\terror: `unknown shorthand flag: 'z' in -z`,\n\t\t},\n\t\t{\n\t\t\targs:  []string{\"-a\", \"stdout\", \"-z\", \"ubuntu\", \"bash\"},\n\t\t\terror: `unknown shorthand flag: 'z' in -z`,\n\t\t},\n\t\t{\n\t\t\targs:  []string{\"-a\", \"stderr\", \"-z\", \"ubuntu\", \"bash\"},\n\t\t\terror: `unknown shorthand flag: 'z' in -z`,\n\t\t},\n\t\t{\n\t\t\targs:  []string{\"-z\", \"--rm\", \"ubuntu\", \"bash\"},\n\t\t\terror: `unknown shorthand flag: 'z' in -z`,\n\t\t},\n\t}\n\tflags, _ := setupRunFlags()\n\tfor _, tc := range tests {\n\t\tt.Run(strings.Join(tc.args, \" \"), func(t *testing.T) {\n\t\t\tassert.Error(t, flags.Parse(tc.args), tc.error)\n\t\t})\n\t}\n}\n\n//nolint:gocyclo\nfunc TestParseWithVolumes(t *testing.T) {\n\n\t// A single volume\n\tarr, tryit := setupPlatformVolume([]string{`/tmp`}, []string{`c:\\tmp`})\n\tif config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds != nil {\n\t\tt.Fatalf(\"Error parsing volume flags, %q should not mount-bind anything. Received %v\", tryit, hostConfig.Binds)\n\t} else if _, exists := config.Volumes[arr[0]]; !exists {\n\t\tt.Fatalf(\"Error parsing volume flags, %q is missing from volumes. Received %v\", tryit, config.Volumes)\n\t}\n\n\t// Two volumes\n\tarr, tryit = setupPlatformVolume([]string{`/tmp`, `/var`}, []string{`c:\\tmp`, `c:\\var`})\n\tif config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds != nil {\n\t\tt.Fatalf(\"Error parsing volume flags, %q should not mount-bind anything. Received %v\", tryit, hostConfig.Binds)\n\t} else if _, exists := config.Volumes[arr[0]]; !exists {\n\t\tt.Fatalf(\"Error parsing volume flags, %s is missing from volumes. Received %v\", arr[0], config.Volumes)\n\t} else if _, exists := config.Volumes[arr[1]]; !exists {\n\t\tt.Fatalf(\"Error parsing volume flags, %s is missing from volumes. Received %v\", arr[1], config.Volumes)\n\t}\n\n\t// A single bind mount\n\tarr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp`}, []string{os.Getenv(\"TEMP\") + `:c:\\containerTmp`})\n\tif config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || hostConfig.Binds[0] != arr[0] {\n\t\tt.Fatalf(\"Error parsing volume flags, %q should mount-bind the path before the colon into the path after the colon. Received %v %v\", arr[0], hostConfig.Binds, config.Volumes)\n\t}\n\n\t// Two bind mounts.\n\tarr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp`, `/hostVar:/containerVar`}, []string{os.Getenv(\"ProgramData\") + `:c:\\ContainerPD`, os.Getenv(\"TEMP\") + `:c:\\containerTmp`})\n\tif _, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {\n\t\tt.Fatalf(\"Error parsing volume flags, `%s and %s` did not mount-bind correctly. Received %v\", arr[0], arr[1], hostConfig.Binds)\n\t}\n\n\t// Two bind mounts, first read-only, second read-write.\n\t// TODO Windows: The Windows version uses read-write as that's the only mode it supports. Can change this post TP4\n\tarr, tryit = setupPlatformVolume(\n\t\t[]string{`/hostTmp:/containerTmp:ro`, `/hostVar:/containerVar:rw`},\n\t\t[]string{os.Getenv(\"TEMP\") + `:c:\\containerTmp:rw`, os.Getenv(\"ProgramData\") + `:c:\\ContainerPD:rw`})\n\tif _, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {\n\t\tt.Fatalf(\"Error parsing volume flags, `%s and %s` did not mount-bind correctly. Received %v\", arr[0], arr[1], hostConfig.Binds)\n\t}\n\n\t// Similar to previous test but with alternate modes which are only supported by Linux\n\tif runtime.GOOS != \"windows\" {\n\t\tarr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp:ro,Z`, `/hostVar:/containerVar:rw,Z`}, []string{})\n\t\tif _, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {\n\t\t\tt.Fatalf(\"Error parsing volume flags, `%s and %s` did not mount-bind correctly. Received %v\", arr[0], arr[1], hostConfig.Binds)\n\t\t}\n\n\t\tarr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp:Z`, `/hostVar:/containerVar:z`}, []string{})\n\t\tif _, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || compareRandomizedStrings(hostConfig.Binds[0], hostConfig.Binds[1], arr[0], arr[1]) != nil {\n\t\t\tt.Fatalf(\"Error parsing volume flags, `%s and %s` did not mount-bind correctly. Received %v\", arr[0], arr[1], hostConfig.Binds)\n\t\t}\n\t}\n\n\t// One bind mount and one volume\n\tarr, tryit = setupPlatformVolume([]string{`/hostTmp:/containerTmp`, `/containerVar`}, []string{os.Getenv(\"TEMP\") + `:c:\\containerTmp`, `c:\\containerTmp`})\n\tif config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || len(hostConfig.Binds) > 1 || hostConfig.Binds[0] != arr[0] {\n\t\tt.Fatalf(\"Error parsing volume flags, %s and %s should only one and only one bind mount %s. Received %s\", arr[0], arr[1], arr[0], hostConfig.Binds)\n\t} else if _, exists := config.Volumes[arr[1]]; !exists {\n\t\tt.Fatalf(\"Error parsing volume flags %s and %s. %s is missing from volumes. Received %v\", arr[0], arr[1], arr[1], config.Volumes)\n\t}\n\n\t// Root to non-c: drive letter (Windows specific)\n\tif runtime.GOOS == \"windows\" {\n\t\tarr, tryit = setupPlatformVolume([]string{}, []string{os.Getenv(\"SystemDrive\") + `\\:d:`})\n\t\tif config, hostConfig, _ := mustParse(t, tryit); hostConfig.Binds == nil || len(hostConfig.Binds) > 1 || hostConfig.Binds[0] != arr[0] || len(config.Volumes) != 0 {\n\t\t\tt.Fatalf(\"Error parsing %s. Should have a single bind mount and no volumes\", arr[0])\n\t\t}\n\t}\n\n}\n\n// setupPlatformVolume takes two arrays of volume specs - a Unix style\n// spec and a Windows style spec. Depending on the platform being unit tested,\n// it returns one of them, along with a volume string that would be passed\n// on the docker CLI (e.g. -v /bar -v /foo).\nfunc setupPlatformVolume(u []string, w []string) ([]string, string) {\n\tvar a []string\n\tif runtime.GOOS == \"windows\" {\n\t\ta = w\n\t} else {\n\t\ta = u\n\t}\n\ts := \"\"\n\tfor _, v := range a {\n\t\ts = s + \"-v \" + v + \" \"\n\t}\n\treturn a, s\n}\n\n// check if (a == c && b == d) || (a == d && b == c)\n// because maps are randomized\nfunc compareRandomizedStrings(a, b, c, d string) error {\n\tif a == c && b == d {\n\t\treturn nil\n\t}\n\tif a == d && b == c {\n\t\treturn nil\n\t}\n\treturn errors.Errorf(\"strings don't match\")\n}\n\n// Simple parse with MacAddress validation\nfunc TestParseWithMacAddress(t *testing.T) {\n\tinvalidMacAddress := \"--mac-address=invalidMacAddress\"\n\tvalidMacAddress := \"--mac-address=92:d0:c6:0a:29:33\"\n\tif _, _, _, err := parseRun([]string{invalidMacAddress, \"img\", \"cmd\"}); err != nil && err.Error() != \"invalidMacAddress is not a valid mac address\" {\n\t\tt.Fatalf(\"Expected an error with %v mac-address, got %v\", invalidMacAddress, err)\n\t}\n\tconfig, hostConfig, _ := mustParse(t, validMacAddress)\n\tfmt.Printf(\"MacAddress: %+v\\n\", hostConfig)\n\tassert.Equal(t, \"92:d0:c6:0a:29:33\", config.MacAddress) //nolint:staticcheck\n}\n\nfunc TestRunFlagsParseWithMemory(t *testing.T) {\n\tflags, _ := setupRunFlags()\n\targs := []string{\"--memory=invalid\", \"img\", \"cmd\"}\n\terr := flags.Parse(args)\n\tassert.ErrorContains(t, err, `invalid argument \"invalid\" for \"-m, --memory\" flag`)\n\n\t_, hostconfig, _ := mustParse(t, \"--memory=1G\")\n\tassert.Check(t, is.Equal(int64(1073741824), hostconfig.Memory))\n}\n\nfunc TestParseWithMemorySwap(t *testing.T) {\n\tflags, _ := setupRunFlags()\n\targs := []string{\"--memory-swap=invalid\", \"img\", \"cmd\"}\n\terr := flags.Parse(args)\n\tassert.ErrorContains(t, err, `invalid argument \"invalid\" for \"--memory-swap\" flag`)\n\n\t_, hostconfig, _ := mustParse(t, \"--memory-swap=1G\")\n\tassert.Check(t, is.Equal(int64(1073741824), hostconfig.MemorySwap))\n\n\t_, hostconfig, _ = mustParse(t, \"--memory-swap=-1\")\n\tassert.Check(t, is.Equal(int64(-1), hostconfig.MemorySwap))\n}\n\nfunc TestParseHostname(t *testing.T) {\n\tvalidHostnames := map[string]string{\n\t\t\"hostname\":    \"hostname\",\n\t\t\"host-name\":   \"host-name\",\n\t\t\"hostname123\": \"hostname123\",\n\t\t\"123hostname\": \"123hostname\",\n\t\t\"hostname-of-63-bytes-long-should-be-valid-and-without-any-error\": \"hostname-of-63-bytes-long-should-be-valid-and-without-any-error\",\n\t}\n\thostnameWithDomain := \"--hostname=hostname.domainname\"\n\thostnameWithDomainTld := \"--hostname=hostname.domainname.tld\"\n\tfor hostname, expectedHostname := range validHostnames {\n\t\tif config, _, _ := mustParse(t, fmt.Sprintf(\"--hostname=%s\", hostname)); config.Hostname != expectedHostname {\n\t\t\tt.Fatalf(\"Expected the config to have 'hostname' as %q, got %q\", expectedHostname, config.Hostname)\n\t\t}\n\t}\n\tif config, _, _ := mustParse(t, hostnameWithDomain); config.Hostname != \"hostname.domainname\" || config.Domainname != \"\" {\n\t\tt.Fatalf(\"Expected the config to have 'hostname' as hostname.domainname, got %q\", config.Hostname)\n\t}\n\tif config, _, _ := mustParse(t, hostnameWithDomainTld); config.Hostname != \"hostname.domainname.tld\" || config.Domainname != \"\" {\n\t\tt.Fatalf(\"Expected the config to have 'hostname' as hostname.domainname.tld, got %q\", config.Hostname)\n\t}\n}\n\nfunc TestParseHostnameDomainname(t *testing.T) {\n\tvalidDomainnames := map[string]string{\n\t\t\"domainname\":    \"domainname\",\n\t\t\"domain-name\":   \"domain-name\",\n\t\t\"domainname123\": \"domainname123\",\n\t\t\"123domainname\": \"123domainname\",\n\t\t\"domainname-63-bytes-long-should-be-valid-and-without-any-errors\": \"domainname-63-bytes-long-should-be-valid-and-without-any-errors\",\n\t}\n\tfor domainname, expectedDomainname := range validDomainnames {\n\t\tif config, _, _ := mustParse(t, \"--domainname=\"+domainname); config.Domainname != expectedDomainname {\n\t\t\tt.Fatalf(\"Expected the config to have 'domainname' as %q, got %q\", expectedDomainname, config.Domainname)\n\t\t}\n\t}\n\tif config, _, _ := mustParse(t, \"--hostname=some.prefix --domainname=domainname\"); config.Hostname != \"some.prefix\" || config.Domainname != \"domainname\" {\n\t\tt.Fatalf(\"Expected the config to have 'hostname' as 'some.prefix' and 'domainname' as 'domainname', got %q and %q\", config.Hostname, config.Domainname)\n\t}\n\tif config, _, _ := mustParse(t, \"--hostname=another-prefix --domainname=domainname.tld\"); config.Hostname != \"another-prefix\" || config.Domainname != \"domainname.tld\" {\n\t\tt.Fatalf(\"Expected the config to have 'hostname' as 'another-prefix' and 'domainname' as 'domainname.tld', got %q and %q\", config.Hostname, config.Domainname)\n\t}\n}\n\nfunc TestParseWithExpose(t *testing.T) {\n\tinvalids := map[string]string{\n\t\t\":\":                   \"invalid port format for --expose: :\",\n\t\t\"8080:9090\":           \"invalid port format for --expose: 8080:9090\",\n\t\t\"/tcp\":                \"invalid range format for --expose: /tcp, error: empty string specified for ports\",\n\t\t\"/udp\":                \"invalid range format for --expose: /udp, error: empty string specified for ports\",\n\t\t\"NaN/tcp\":             `invalid range format for --expose: NaN/tcp, error: strconv.ParseUint: parsing \"NaN\": invalid syntax`,\n\t\t\"NaN-NaN/tcp\":         `invalid range format for --expose: NaN-NaN/tcp, error: strconv.ParseUint: parsing \"NaN\": invalid syntax`,\n\t\t\"8080-NaN/tcp\":        `invalid range format for --expose: 8080-NaN/tcp, error: strconv.ParseUint: parsing \"NaN\": invalid syntax`,\n\t\t\"1234567890-8080/tcp\": `invalid range format for --expose: 1234567890-8080/tcp, error: strconv.ParseUint: parsing \"1234567890\": value out of range`,\n\t}\n\tvalids := map[string][]nat.Port{\n\t\t\"8080/tcp\":      {\"8080/tcp\"},\n\t\t\"8080/udp\":      {\"8080/udp\"},\n\t\t\"8080/ncp\":      {\"8080/ncp\"},\n\t\t\"8080-8080/udp\": {\"8080/udp\"},\n\t\t\"8080-8082/tcp\": {\"8080/tcp\", \"8081/tcp\", \"8082/tcp\"},\n\t}\n\tfor expose, expectedError := range invalids {\n\t\tif _, _, _, err := parseRun([]string{fmt.Sprintf(\"--expose=%v\", expose), \"img\", \"cmd\"}); err == nil || err.Error() != expectedError {\n\t\t\tt.Fatalf(\"Expected error '%v' with '--expose=%v', got '%v'\", expectedError, expose, err)\n\t\t}\n\t}\n\tfor expose, exposedPorts := range valids {\n\t\tconfig, _, _, err := parseRun([]string{fmt.Sprintf(\"--expose=%v\", expose), \"img\", \"cmd\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(config.ExposedPorts) != len(exposedPorts) {\n\t\t\tt.Fatalf(\"Expected %v exposed port, got %v\", len(exposedPorts), len(config.ExposedPorts))\n\t\t}\n\t\tfor _, port := range exposedPorts {\n\t\t\tif _, ok := config.ExposedPorts[port]; !ok {\n\t\t\t\tt.Fatalf(\"Expected %v, got %v\", exposedPorts, config.ExposedPorts)\n\t\t\t}\n\t\t}\n\t}\n\t// Merge with actual published port\n\tconfig, _, _, err := parseRun([]string{\"--publish=80\", \"--expose=80-81/tcp\", \"img\", \"cmd\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif len(config.ExposedPorts) != 2 {\n\t\tt.Fatalf(\"Expected 2 exposed ports, got %v\", config.ExposedPorts)\n\t}\n\tports := []nat.Port{\"80/tcp\", \"81/tcp\"}\n\tfor _, port := range ports {\n\t\tif _, ok := config.ExposedPorts[port]; !ok {\n\t\t\tt.Fatalf(\"Expected %v, got %v\", ports, config.ExposedPorts)\n\t\t}\n\t}\n}\n\nfunc TestParseDevice(t *testing.T) {\n\tskip.If(t, runtime.GOOS != \"linux\") // Windows and macOS validate server-side\n\tvalids := map[string]container.DeviceMapping{\n\t\t\"/dev/snd\": {\n\t\t\tPathOnHost:        \"/dev/snd\",\n\t\t\tPathInContainer:   \"/dev/snd\",\n\t\t\tCgroupPermissions: \"rwm\",\n\t\t},\n\t\t\"/dev/snd:rw\": {\n\t\t\tPathOnHost:        \"/dev/snd\",\n\t\t\tPathInContainer:   \"/dev/snd\",\n\t\t\tCgroupPermissions: \"rw\",\n\t\t},\n\t\t\"/dev/snd:/something\": {\n\t\t\tPathOnHost:        \"/dev/snd\",\n\t\t\tPathInContainer:   \"/something\",\n\t\t\tCgroupPermissions: \"rwm\",\n\t\t},\n\t\t\"/dev/snd:/something:rw\": {\n\t\t\tPathOnHost:        \"/dev/snd\",\n\t\t\tPathInContainer:   \"/something\",\n\t\t\tCgroupPermissions: \"rw\",\n\t\t},\n\t}\n\tfor device, deviceMapping := range valids {\n\t\t_, hostconfig, _, err := parseRun([]string{fmt.Sprintf(\"--device=%v\", device), \"img\", \"cmd\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(hostconfig.Devices) != 1 {\n\t\t\tt.Fatalf(\"Expected 1 devices, got %v\", hostconfig.Devices)\n\t\t}\n\t\tif hostconfig.Devices[0] != deviceMapping {\n\t\t\tt.Fatalf(\"Expected %v, got %v\", deviceMapping, hostconfig.Devices)\n\t\t}\n\t}\n\n}\n\nfunc TestParseNetworkConfig(t *testing.T) {\n\ttests := []struct {\n\t\tname        string\n\t\tflags       []string\n\t\texpected    map[string]*networktypes.EndpointSettings\n\t\texpectedCfg container.HostConfig\n\t\texpectedErr string\n\t}{\n\t\t{\n\t\t\tname:        \"single-network-legacy\",\n\t\t\tflags:       []string{\"--network\", \"net1\"},\n\t\t\texpected:    map[string]*networktypes.EndpointSettings{},\n\t\t\texpectedCfg: container.HostConfig{NetworkMode: \"net1\"},\n\t\t},\n\t\t{\n\t\t\tname:        \"single-network-advanced\",\n\t\t\tflags:       []string{\"--network\", \"name=net1\"},\n\t\t\texpected:    map[string]*networktypes.EndpointSettings{},\n\t\t\texpectedCfg: container.HostConfig{NetworkMode: \"net1\"},\n\t\t},\n\t\t{\n\t\t\tname: \"single-network-legacy-with-options\",\n\t\t\tflags: []string{\n\t\t\t\t\"--ip\", \"172.20.88.22\",\n\t\t\t\t\"--ip6\", \"2001:db8::8822\",\n\t\t\t\t\"--link\", \"foo:bar\",\n\t\t\t\t\"--link\", \"bar:baz\",\n\t\t\t\t\"--link-local-ip\", \"169.254.2.2\",\n\t\t\t\t\"--link-local-ip\", \"fe80::169:254:2:2\",\n\t\t\t\t\"--network\", \"name=net1\",\n\t\t\t\t\"--network-alias\", \"web1\",\n\t\t\t\t\"--network-alias\", \"web2\",\n\t\t\t},\n\t\t\texpected: map[string]*networktypes.EndpointSettings{\n\t\t\t\t\"net1\": {\n\t\t\t\t\tIPAMConfig: &networktypes.EndpointIPAMConfig{\n\t\t\t\t\t\tIPv4Address:  \"172.20.88.22\",\n\t\t\t\t\t\tIPv6Address:  \"2001:db8::8822\",\n\t\t\t\t\t\tLinkLocalIPs: []string{\"169.254.2.2\", \"fe80::169:254:2:2\"},\n\t\t\t\t\t},\n\t\t\t\t\tLinks:   []string{\"foo:bar\", \"bar:baz\"},\n\t\t\t\t\tAliases: []string{\"web1\", \"web2\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedCfg: container.HostConfig{NetworkMode: \"net1\"},\n\t\t},\n\t\t{\n\t\t\tname: \"multiple-network-advanced-mixed\",\n\t\t\tflags: []string{\n\t\t\t\t\"--ip\", \"172.20.88.22\",\n\t\t\t\t\"--ip6\", \"2001:db8::8822\",\n\t\t\t\t\"--link\", \"foo:bar\",\n\t\t\t\t\"--link\", \"bar:baz\",\n\t\t\t\t\"--link-local-ip\", \"169.254.2.2\",\n\t\t\t\t\"--link-local-ip\", \"fe80::169:254:2:2\",\n\t\t\t\t\"--network\", \"name=net1,driver-opt=field1=value1\",\n\t\t\t\t\"--network-alias\", \"web1\",\n\t\t\t\t\"--network-alias\", \"web2\",\n\t\t\t\t\"--network\", \"net2\",\n\t\t\t\t\"--network\", \"name=net3,alias=web3,driver-opt=field3=value3,ip=172.20.88.22,ip6=2001:db8::8822\",\n\t\t\t},\n\t\t\texpected: map[string]*networktypes.EndpointSettings{\n\t\t\t\t\"net1\": {\n\t\t\t\t\tDriverOpts: map[string]string{\"field1\": \"value1\"},\n\t\t\t\t\tIPAMConfig: &networktypes.EndpointIPAMConfig{\n\t\t\t\t\t\tIPv4Address:  \"172.20.88.22\",\n\t\t\t\t\t\tIPv6Address:  \"2001:db8::8822\",\n\t\t\t\t\t\tLinkLocalIPs: []string{\"169.254.2.2\", \"fe80::169:254:2:2\"},\n\t\t\t\t\t},\n\t\t\t\t\tLinks:   []string{\"foo:bar\", \"bar:baz\"},\n\t\t\t\t\tAliases: []string{\"web1\", \"web2\"},\n\t\t\t\t},\n\t\t\t\t\"net2\": {},\n\t\t\t\t\"net3\": {\n\t\t\t\t\tDriverOpts: map[string]string{\"field3\": \"value3\"},\n\t\t\t\t\tIPAMConfig: &networktypes.EndpointIPAMConfig{\n\t\t\t\t\t\tIPv4Address: \"172.20.88.22\",\n\t\t\t\t\t\tIPv6Address: \"2001:db8::8822\",\n\t\t\t\t\t},\n\t\t\t\t\tAliases: []string{\"web3\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedCfg: container.HostConfig{NetworkMode: \"net1\"},\n\t\t},\n\t\t{\n\t\t\tname:  \"single-network-advanced-with-options\",\n\t\t\tflags: []string{\"--network\", \"name=net1,alias=web1,alias=web2,driver-opt=field1=value1,driver-opt=field2=value2,ip=172.20.88.22,ip6=2001:db8::8822\"},\n\t\t\texpected: map[string]*networktypes.EndpointSettings{\n\t\t\t\t\"net1\": {\n\t\t\t\t\tDriverOpts: map[string]string{\n\t\t\t\t\t\t\"field1\": \"value1\",\n\t\t\t\t\t\t\"field2\": \"value2\",\n\t\t\t\t\t},\n\t\t\t\t\tIPAMConfig: &networktypes.EndpointIPAMConfig{\n\t\t\t\t\t\tIPv4Address: \"172.20.88.22\",\n\t\t\t\t\t\tIPv6Address: \"2001:db8::8822\",\n\t\t\t\t\t},\n\t\t\t\t\tAliases: []string{\"web1\", \"web2\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedCfg: container.HostConfig{NetworkMode: \"net1\"},\n\t\t},\n\t\t{\n\t\t\tname:        \"multiple-networks\",\n\t\t\tflags:       []string{\"--network\", \"net1\", \"--network\", \"name=net2\"},\n\t\t\texpected:    map[string]*networktypes.EndpointSettings{\"net1\": {}, \"net2\": {}},\n\t\t\texpectedCfg: container.HostConfig{NetworkMode: \"net1\"},\n\t\t},\n\t\t{\n\t\t\tname:        \"conflict-network\",\n\t\t\tflags:       []string{\"--network\", \"duplicate\", \"--network\", \"name=duplicate\"},\n\t\t\texpectedErr: `network \"duplicate\" is specified multiple times`,\n\t\t},\n\t\t{\n\t\t\tname:        \"conflict-options-alias\",\n\t\t\tflags:       []string{\"--network\", \"name=net1,alias=web1\", \"--network-alias\", \"web1\"},\n\t\t\texpectedErr: `conflicting options: cannot specify both --network-alias and per-network alias`,\n\t\t},\n\t\t{\n\t\t\tname:        \"conflict-options-ip\",\n\t\t\tflags:       []string{\"--network\", \"name=net1,ip=172.20.88.22,ip6=2001:db8::8822\", \"--ip\", \"172.20.88.22\"},\n\t\t\texpectedErr: `conflicting options: cannot specify both --ip and per-network IPv4 address`,\n\t\t},\n\t\t{\n\t\t\tname:        \"conflict-options-ip6\",\n\t\t\tflags:       []string{\"--network\", \"name=net1,ip=172.20.88.22,ip6=2001:db8::8822\", \"--ip6\", \"2001:db8::8822\"},\n\t\t\texpectedErr: `conflicting options: cannot specify both --ip6 and per-network IPv6 address`,\n\t\t},\n\t\t// case is skipped as it fails w/o any change\n\t\t//\n\t\t//{\n\t\t//\tname:        \"invalid-mixed-network-types\",\n\t\t//\tflags:       []string{\"--network\", \"name=host\", \"--network\", \"net1\"},\n\t\t//\texpectedErr: `conflicting options: cannot attach both user-defined and non-user-defined network-modes`,\n\t\t//},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t_, hConfig, nwConfig, err := parseRun(tc.flags)\n\n\t\t\tif tc.expectedErr != \"\" {\n\t\t\t\tassert.Error(t, err, tc.expectedErr)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.DeepEqual(t, hConfig.NetworkMode, tc.expectedCfg.NetworkMode)\n\t\t\tassert.DeepEqual(t, nwConfig.EndpointsConfig, tc.expected)\n\t\t})\n\t}\n}\n\nfunc TestParseModes(t *testing.T) {\n\t// pid ko\n\tflags, copts := setupRunFlags()\n\targs := []string{\"--pid=container:\", \"img\", \"cmd\"}\n\tassert.NilError(t, flags.Parse(args))\n\t_, err := parse(flags, copts, runtime.GOOS)\n\tassert.ErrorContains(t, err, \"--pid: invalid PID mode\")\n\n\t// pid ok\n\t_, hostconfig, _, err := parseRun([]string{\"--pid=host\", \"img\", \"cmd\"})\n\tassert.NilError(t, err)\n\tif !hostconfig.PidMode.Valid() {\n\t\tt.Fatalf(\"Expected a valid PidMode, got %v\", hostconfig.PidMode)\n\t}\n\n\t// uts ko\n\t_, _, _, err = parseRun([]string{\"--uts=container:\", \"img\", \"cmd\"}) //nolint:dogsled\n\tassert.ErrorContains(t, err, \"--uts: invalid UTS mode\")\n\n\t// uts ok\n\t_, hostconfig, _, err = parseRun([]string{\"--uts=host\", \"img\", \"cmd\"})\n\tassert.NilError(t, err)\n\tif !hostconfig.UTSMode.Valid() {\n\t\tt.Fatalf(\"Expected a valid UTSMode, got %v\", hostconfig.UTSMode)\n\t}\n}\n\nfunc TestRunFlagsParseShmSize(t *testing.T) {\n\t// shm-size ko\n\tflags, _ := setupRunFlags()\n\targs := []string{\"--shm-size=a128m\", \"img\", \"cmd\"}\n\texpectedErr := `invalid argument \"a128m\" for \"--shm-size\" flag:`\n\terr := flags.Parse(args)\n\tassert.ErrorContains(t, err, expectedErr)\n\n\t// shm-size ok\n\t_, hostconfig, _, err := parseRun([]string{\"--shm-size=128m\", \"img\", \"cmd\"})\n\tassert.NilError(t, err)\n\tif hostconfig.ShmSize != 134217728 {\n\t\tt.Fatalf(\"Expected a valid ShmSize, got %d\", hostconfig.ShmSize)\n\t}\n}\n\nfunc TestParseRestartPolicy(t *testing.T) {\n\tinvalids := map[string]string{\n\t\t\"always:2:3\":         \"invalid restart policy format: maximum retry count must be an integer\",\n\t\t\"on-failure:invalid\": \"invalid restart policy format: maximum retry count must be an integer\",\n\t}\n\tvalids := map[string]container.RestartPolicy{\n\t\t\"\": {},\n\t\t\"always\": {\n\t\t\tName:              \"always\",\n\t\t\tMaximumRetryCount: 0,\n\t\t},\n\t\t\"on-failure:1\": {\n\t\t\tName:              \"on-failure\",\n\t\t\tMaximumRetryCount: 1,\n\t\t},\n\t}\n\tfor restart, expectedError := range invalids {\n\t\tif _, _, _, err := parseRun([]string{fmt.Sprintf(\"--restart=%s\", restart), \"img\", \"cmd\"}); err == nil || err.Error() != expectedError {\n\t\t\tt.Fatalf(\"Expected an error with message '%v' for %v, got %v\", expectedError, restart, err)\n\t\t}\n\t}\n\tfor restart, expected := range valids {\n\t\t_, hostconfig, _, err := parseRun([]string{fmt.Sprintf(\"--restart=%v\", restart), \"img\", \"cmd\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif hostconfig.RestartPolicy != expected {\n\t\t\tt.Fatalf(\"Expected %v, got %v\", expected, hostconfig.RestartPolicy)\n\t\t}\n\t}\n}\n\nfunc TestParseRestartPolicyAutoRemove(t *testing.T) {\n\texpected := \"Conflicting options: --restart and --rm\"\n\t_, _, _, err := parseRun([]string{\"--rm\", \"--restart=always\", \"img\", \"cmd\"}) //nolint:dogsled\n\tif err == nil || err.Error() != expected {\n\t\tt.Fatalf(\"Expected error %v, but got none\", expected)\n\t}\n}\n\nfunc TestParseHealth(t *testing.T) {\n\tcheckOk := func(args ...string) *container.HealthConfig {\n\t\tconfig, _, _, err := parseRun(args)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"%#v: %v\", args, err)\n\t\t}\n\t\treturn config.Healthcheck\n\t}\n\tcheckError := func(expected string, args ...string) {\n\t\tconfig, _, _, err := parseRun(args)\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"Expected error, but got %#v\", config)\n\t\t}\n\t\tif err.Error() != expected {\n\t\t\tt.Fatalf(\"Expected %#v, got %#v\", expected, err)\n\t\t}\n\t}\n\thealth := checkOk(\"--no-healthcheck\", \"img\", \"cmd\")\n\tif health == nil || len(health.Test) != 1 || health.Test[0] != \"NONE\" {\n\t\tt.Fatalf(\"--no-healthcheck failed: %#v\", health)\n\t}\n\n\thealth = checkOk(\"--health-cmd=/check.sh -q\", \"img\", \"cmd\")\n\tif len(health.Test) != 2 || health.Test[0] != \"CMD-SHELL\" || health.Test[1] != \"/check.sh -q\" {\n\t\tt.Fatalf(\"--health-cmd: got %#v\", health.Test)\n\t}\n\tif health.Timeout != 0 {\n\t\tt.Fatalf(\"--health-cmd: timeout = %s\", health.Timeout)\n\t}\n\n\tcheckError(\"--no-healthcheck conflicts with --health-* options\",\n\t\t\"--no-healthcheck\", \"--health-cmd=/check.sh -q\", \"img\", \"cmd\")\n\n\thealth = checkOk(\"--health-timeout=2s\", \"--health-retries=3\", \"--health-interval=4.5s\", \"--health-start-period=5s\", \"img\", \"cmd\")\n\tif health.Timeout != 2*time.Second || health.Retries != 3 || health.Interval != 4500*time.Millisecond || health.StartPeriod != 5*time.Second {\n\t\tt.Fatalf(\"--health-*: got %#v\", health)\n\t}\n}\n\nfunc TestParseLoggingOpts(t *testing.T) {\n\t// logging opts ko\n\tif _, _, _, err := parseRun([]string{\"--log-driver=none\", \"--log-opt=anything\", \"img\", \"cmd\"}); err == nil || err.Error() != \"invalid logging opts for driver none\" {\n\t\tt.Fatalf(\"Expected an error with message 'invalid logging opts for driver none', got %v\", err)\n\t}\n\t// logging opts ok\n\t_, hostconfig, _, err := parseRun([]string{\"--log-driver=syslog\", \"--log-opt=something\", \"img\", \"cmd\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif hostconfig.LogConfig.Type != \"syslog\" || len(hostconfig.LogConfig.Config) != 1 {\n\t\tt.Fatalf(\"Expected a 'syslog' LogConfig with one config, got %v\", hostconfig.RestartPolicy)\n\t}\n}\n\nfunc TestParseEnvfileVariables(t *testing.T) {\n\te := \"open nonexistent: no such file or directory\"\n\tif runtime.GOOS == \"windows\" {\n\t\te = \"open nonexistent: The system cannot find the file specified.\"\n\t}\n\t// env ko\n\tif _, _, _, err := parseRun([]string{\"--env-file=nonexistent\", \"img\", \"cmd\"}); err == nil || err.Error() != e {\n\t\tt.Fatalf(\"Expected an error with message '%s', got %v\", e, err)\n\t}\n\t// env ok\n\tconfig, _, _, err := parseRun([]string{\"--env-file=testdata/valid.env\", \"img\", \"cmd\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif len(config.Env) != 1 || config.Env[0] != \"ENV1=value1\" {\n\t\tt.Fatalf(\"Expected a config with [ENV1=value1], got %v\", config.Env)\n\t}\n\tconfig, _, _, err = parseRun([]string{\"--env-file=testdata/valid.env\", \"--env=ENV2=value2\", \"img\", \"cmd\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif len(config.Env) != 2 || config.Env[0] != \"ENV1=value1\" || config.Env[1] != \"ENV2=value2\" {\n\t\tt.Fatalf(\"Expected a config with [ENV1=value1 ENV2=value2], got %v\", config.Env)\n\t}\n}\n\nfunc TestParseEnvfileVariablesWithBOMUnicode(t *testing.T) {\n\t// UTF8 with BOM\n\tconfig, _, _, err := parseRun([]string{\"--env-file=testdata/utf8.env\", \"img\", \"cmd\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tenv := []string{\"FOO=BAR\", \"HELLO=\" + string([]byte{0xe6, 0x82, 0xa8, 0xe5, 0xa5, 0xbd}), \"BAR=FOO\"}\n\tif len(config.Env) != len(env) {\n\t\tt.Fatalf(\"Expected a config with %d env variables, got %v: %v\", len(env), len(config.Env), config.Env)\n\t}\n\tfor i, v := range env {\n\t\tif config.Env[i] != v {\n\t\t\tt.Fatalf(\"Expected a config with [%s], got %v\", v, []byte(config.Env[i]))\n\t\t}\n\t}\n\n\t// UTF16 with BOM\n\te := \"invalid env file\"\n\tif _, _, _, err := parseRun([]string{\"--env-file=testdata/utf16.env\", \"img\", \"cmd\"}); err == nil || !strings.Contains(err.Error(), e) {\n\t\tt.Fatalf(\"Expected an error with message '%s', got %v\", e, err)\n\t}\n\t// UTF16BE with BOM\n\tif _, _, _, err := parseRun([]string{\"--env-file=testdata/utf16be.env\", \"img\", \"cmd\"}); err == nil || !strings.Contains(err.Error(), e) {\n\t\tt.Fatalf(\"Expected an error with message '%s', got %v\", e, err)\n\t}\n}\n\nfunc TestParseLabelfileVariables(t *testing.T) {\n\te := \"open nonexistent: no such file or directory\"\n\tif runtime.GOOS == \"windows\" {\n\t\te = \"open nonexistent: The system cannot find the file specified.\"\n\t}\n\t// label ko\n\tif _, _, _, err := parseRun([]string{\"--label-file=nonexistent\", \"img\", \"cmd\"}); err == nil || err.Error() != e {\n\t\tt.Fatalf(\"Expected an error with message '%s', got %v\", e, err)\n\t}\n\t// label ok\n\tconfig, _, _, err := parseRun([]string{\"--label-file=testdata/valid.label\", \"img\", \"cmd\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif len(config.Labels) != 1 || config.Labels[\"LABEL1\"] != \"value1\" {\n\t\tt.Fatalf(\"Expected a config with [LABEL1:value1], got %v\", config.Labels)\n\t}\n\tconfig, _, _, err = parseRun([]string{\"--label-file=testdata/valid.label\", \"--label=LABEL2=value2\", \"img\", \"cmd\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif len(config.Labels) != 2 || config.Labels[\"LABEL1\"] != \"value1\" || config.Labels[\"LABEL2\"] != \"value2\" {\n\t\tt.Fatalf(\"Expected a config with [LABEL1:value1 LABEL2:value2], got %v\", config.Labels)\n\t}\n}\n\nfunc TestParseEntryPoint(t *testing.T) {\n\tconfig, _, _, err := parseRun([]string{\"--entrypoint=anything\", \"cmd\", \"img\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif len(config.Entrypoint) != 1 && config.Entrypoint[0] != \"anything\" {\n\t\tt.Fatalf(\"Expected entrypoint 'anything', got %v\", config.Entrypoint)\n\t}\n}\n\nfunc TestValidateDevice(t *testing.T) {\n\tskip.If(t, runtime.GOOS != \"linux\") // Windows and macOS validate server-side\n\tvalid := []string{\n\t\t\"/home\",\n\t\t\"/home:/home\",\n\t\t\"/home:/something/else\",\n\t\t\"/with space\",\n\t\t\"/home:/with space\",\n\t\t\"relative:/absolute-path\",\n\t\t\"hostPath:/containerPath:r\",\n\t\t\"/hostPath:/containerPath:rw\",\n\t\t\"/hostPath:/containerPath:mrw\",\n\t}\n\tinvalid := map[string]string{\n\t\t\"\":        \"bad format for path: \",\n\t\t\"./\":      \"./ is not an absolute path\",\n\t\t\"../\":     \"../ is not an absolute path\",\n\t\t\"/:../\":   \"../ is not an absolute path\",\n\t\t\"/:path\":  \"path is not an absolute path\",\n\t\t\":\":       \"bad format for path: :\",\n\t\t\"/tmp:\":   \" is not an absolute path\",\n\t\t\":test\":   \"bad format for path: :test\",\n\t\t\":/test\":  \"bad format for path: :/test\",\n\t\t\"tmp:\":    \" is not an absolute path\",\n\t\t\":test:\":  \"bad format for path: :test:\",\n\t\t\"::\":      \"bad format for path: ::\",\n\t\t\":::\":     \"bad format for path: :::\",\n\t\t\"/tmp:::\": \"bad format for path: /tmp:::\",\n\t\t\":/tmp::\": \"bad format for path: :/tmp::\",\n\t\t\"path:ro\": \"ro is not an absolute path\",\n\t\t\"path:rr\": \"rr is not an absolute path\",\n\t\t\"a:/b:ro\": \"bad mode specified: ro\",\n\t\t\"a:/b:rr\": \"bad mode specified: rr\",\n\t}\n\n\tfor _, path := range valid {\n\t\tif _, err := validateDevice(path, runtime.GOOS); err != nil {\n\t\t\tt.Fatalf(\"ValidateDevice(`%q`) should succeed: error %q\", path, err)\n\t\t}\n\t}\n\n\tfor path, expectedError := range invalid {\n\t\tif _, err := validateDevice(path, runtime.GOOS); err == nil {\n\t\t\tt.Fatalf(\"ValidateDevice(`%q`) should have failed validation\", path)\n\t\t} else {\n\t\t\tif err.Error() != expectedError {\n\t\t\t\tt.Fatalf(\"ValidateDevice(`%q`) error should contain %q, got %q\", path, expectedError, err.Error())\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc TestParseSystemPaths(t *testing.T) {\n\ttests := []struct {\n\t\tdoc                       string\n\t\tin, out, masked, readonly []string\n\t}{\n\t\t{\n\t\t\tdoc: \"not set\",\n\t\t\tin:  []string{},\n\t\t\tout: []string{},\n\t\t},\n\t\t{\n\t\t\tdoc: \"not set, preserve other options\",\n\t\t\tin: []string{\n\t\t\t\t\"seccomp=unconfined\",\n\t\t\t\t\"apparmor=unconfined\",\n\t\t\t\t\"label=user:USER\",\n\t\t\t\t\"foo=bar\",\n\t\t\t},\n\t\t\tout: []string{\n\t\t\t\t\"seccomp=unconfined\",\n\t\t\t\t\"apparmor=unconfined\",\n\t\t\t\t\"label=user:USER\",\n\t\t\t\t\"foo=bar\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdoc:      \"unconfined\",\n\t\t\tin:       []string{\"systempaths=unconfined\"},\n\t\t\tout:      []string{},\n\t\t\tmasked:   []string{},\n\t\t\treadonly: []string{},\n\t\t},\n\t\t{\n\t\t\tdoc:      \"unconfined and other options\",\n\t\t\tin:       []string{\"foo=bar\", \"bar=baz\", \"systempaths=unconfined\"},\n\t\t\tout:      []string{\"foo=bar\", \"bar=baz\"},\n\t\t\tmasked:   []string{},\n\t\t\treadonly: []string{},\n\t\t},\n\t\t{\n\t\t\tdoc: \"unknown option\",\n\t\t\tin:  []string{\"foo=bar\", \"systempaths=unknown\", \"bar=baz\"},\n\t\t\tout: []string{\"foo=bar\", \"systempaths=unknown\", \"bar=baz\"},\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tsecurityOpts, maskedPaths, readonlyPaths := parseSystemPaths(tc.in)\n\t\tassert.DeepEqual(t, securityOpts, tc.out)\n\t\tassert.DeepEqual(t, maskedPaths, tc.masked)\n\t\tassert.DeepEqual(t, readonlyPaths, tc.readonly)\n\t}\n}\n\nfunc TestConvertToStandardNotation(t *testing.T) {\n\tvalid := map[string][]string{\n\t\t\"20:10/tcp\":               {\"target=10,published=20\"},\n\t\t\"40:30\":                   {\"40:30\"},\n\t\t\"20:20 80:4444\":           {\"20:20\", \"80:4444\"},\n\t\t\"1500:2500/tcp 1400:1300\": {\"target=2500,published=1500\", \"1400:1300\"},\n\t\t\"1500:200/tcp 90:80/tcp\":  {\"published=1500,target=200\", \"target=80,published=90\"},\n\t}\n\n\tinvalid := [][]string{\n\t\t{\"published=1500,target:444\"},\n\t\t{\"published=1500,444\"},\n\t\t{\"published=1500,target,444\"},\n\t}\n\n\tfor key, ports := range valid {\n\t\tconvertedPorts, err := convertToStandardNotation(ports)\n\n\t\tif err != nil {\n\t\t\tassert.NilError(t, err)\n\t\t}\n\t\tassert.DeepEqual(t, strings.Split(key, \" \"), convertedPorts)\n\t}\n\n\tfor _, ports := range invalid {\n\t\tif _, err := convertToStandardNotation(ports); err == nil {\n\t\t\tt.Fatalf(\"ConvertToStandardNotation(`%q`) should have failed conversion\", ports)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/container/docker_images.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tcerrdefs \"github.com/containerd/errdefs\"\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\n// ImageExistsLocally returns a boolean indicating if an image with the\n// requested name, tag and architecture exists in the local docker image store\nfunc ImageExistsLocally(ctx context.Context, imageName string, platform string) (bool, error) {\n\tcli, err := GetDockerClient(ctx)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer cli.Close()\n\n\tinspectImage, err := cli.ImageInspect(ctx, imageName)\n\tif cerrdefs.IsNotFound(err) {\n\t\treturn false, nil\n\t} else if err != nil {\n\t\treturn false, err\n\t}\n\n\timagePlatform := fmt.Sprintf(\"%s/%s\", inspectImage.Os, inspectImage.Architecture)\n\n\tif platform == \"\" || platform == \"any\" || imagePlatform == platform {\n\t\treturn true, nil\n\t}\n\n\tlogger := common.Logger(ctx)\n\tlogger.Infof(\"image found but platform does not match: %s (image) != %s (platform)\\n\", imagePlatform, platform)\n\n\treturn false, nil\n}\n\n// RemoveImage removes image from local store, the function is used to run different\n// container image architectures\nfunc RemoveImage(ctx context.Context, imageName string, force bool, pruneChildren bool) (bool, error) {\n\tcli, err := GetDockerClient(ctx)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer cli.Close()\n\n\tinspectImage, err := cli.ImageInspect(ctx, imageName)\n\tif cerrdefs.IsNotFound(err) {\n\t\treturn false, nil\n\t} else if err != nil {\n\t\treturn false, err\n\t}\n\n\tif _, err = cli.ImageRemove(ctx, inspectImage.ID, image.RemoveOptions{\n\t\tForce:         force,\n\t\tPruneChildren: pruneChildren,\n\t}); err != nil {\n\t\treturn false, err\n\t}\n\n\treturn true, nil\n}\n"
  },
  {
    "path": "pkg/container/docker_images_test.go",
    "content": "package container\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/client\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc init() {\n\tlog.SetLevel(log.DebugLevel)\n}\n\nfunc TestImageExistsLocally(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\tctx := context.Background()\n\t// to help make this test reliable and not flaky, we need to have\n\t// an image that will exist, and onew that won't exist\n\n\t// Test if image exists with specific tag\n\tinvalidImageTag, err := ImageExistsLocally(ctx, \"library/alpine:this-random-tag-will-never-exist\", \"linux/amd64\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, false, invalidImageTag)\n\n\t// Test if image exists with specific architecture (image platform)\n\tinvalidImagePlatform, err := ImageExistsLocally(ctx, \"alpine:latest\", \"windows/amd64\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, false, invalidImagePlatform)\n\n\t// pull an image\n\tcli, err := client.NewClientWithOpts(client.FromEnv)\n\tassert.Nil(t, err)\n\tcli.NegotiateAPIVersion(context.Background())\n\n\t// Chose alpine latest because it's so small\n\t// maybe we should build an image instead so that tests aren't reliable on dockerhub\n\treaderDefault, err := cli.ImagePull(ctx, \"node:16-buster-slim\", image.PullOptions{\n\t\tPlatform: \"linux/amd64\",\n\t})\n\tassert.Nil(t, err)\n\tdefer readerDefault.Close()\n\t_, err = io.ReadAll(readerDefault)\n\tassert.Nil(t, err)\n\n\timageDefaultArchExists, err := ImageExistsLocally(ctx, \"node:16-buster-slim\", \"linux/amd64\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, true, imageDefaultArchExists)\n\n\t// Validate if another architecture platform can be pulled\n\treaderArm64, err := cli.ImagePull(ctx, \"node:16-buster-slim\", image.PullOptions{\n\t\tPlatform: \"linux/arm64\",\n\t})\n\tassert.Nil(t, err)\n\tdefer readerArm64.Close()\n\t_, err = io.ReadAll(readerArm64)\n\tassert.Nil(t, err)\n\n\timageArm64Exists, err := ImageExistsLocally(ctx, \"node:16-buster-slim\", \"linux/arm64\")\n\tassert.Nil(t, err)\n\tassert.Equal(t, true, imageArm64Exists)\n}\n"
  },
  {
    "path": "pkg/container/docker_logger.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"bufio\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\ntype dockerMessage struct {\n\tID          string `json:\"id\"`\n\tStream      string `json:\"stream\"`\n\tError       string `json:\"error\"`\n\tErrorDetail struct {\n\t\tMessage string\n\t}\n\tStatus   string `json:\"status\"`\n\tProgress string `json:\"progress\"`\n}\n\nconst logPrefix = \"  \\U0001F433  \"\n\nfunc logDockerResponse(logger logrus.FieldLogger, dockerResponse io.ReadCloser, isError bool) error {\n\tif dockerResponse == nil {\n\t\treturn nil\n\t}\n\tdefer dockerResponse.Close()\n\n\tscanner := bufio.NewScanner(dockerResponse)\n\tmsg := dockerMessage{}\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Bytes()\n\n\t\tmsg.ID = \"\"\n\t\tmsg.Stream = \"\"\n\t\tmsg.Error = \"\"\n\t\tmsg.ErrorDetail.Message = \"\"\n\t\tmsg.Status = \"\"\n\t\tmsg.Progress = \"\"\n\n\t\tif err := json.Unmarshal(line, &msg); err != nil {\n\t\t\twriteLog(logger, false, \"Unable to unmarshal line [%s] ==> %v\", string(line), err)\n\t\t\tcontinue\n\t\t}\n\n\t\tif msg.Error != \"\" {\n\t\t\twriteLog(logger, isError, \"%s\", msg.Error)\n\t\t\treturn errors.New(msg.Error)\n\t\t}\n\n\t\tif msg.ErrorDetail.Message != \"\" {\n\t\t\twriteLog(logger, isError, \"%s\", msg.ErrorDetail.Message)\n\t\t\treturn errors.New(msg.Error)\n\t\t}\n\n\t\tif msg.Status != \"\" {\n\t\t\tif msg.Progress != \"\" {\n\t\t\t\twriteLog(logger, isError, \"%s :: %s :: %s\\n\", msg.Status, msg.ID, msg.Progress)\n\t\t\t} else {\n\t\t\t\twriteLog(logger, isError, \"%s :: %s\\n\", msg.Status, msg.ID)\n\t\t\t}\n\t\t} else if msg.Stream != \"\" {\n\t\t\twriteLog(logger, isError, \"%s\", msg.Stream)\n\t\t} else {\n\t\t\twriteLog(logger, false, \"Unable to handle line: %s\", string(line))\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc writeLog(logger logrus.FieldLogger, isError bool, format string, args ...interface{}) {\n\tif isError {\n\t\tlogger.Errorf(format, args...)\n\t} else {\n\t\tlogger.Debugf(format, args...)\n\t}\n}\n"
  },
  {
    "path": "pkg/container/docker_network.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types/network\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\nfunc NewDockerNetworkCreateExecutor(name string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tcli, err := GetDockerClient(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer cli.Close()\n\n\t\t// Only create the network if it doesn't exist\n\t\tnetworks, err := cli.NetworkList(ctx, network.ListOptions{})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcommon.Logger(ctx).Debugf(\"%v\", networks)\n\t\tfor _, network := range networks {\n\t\t\tif network.Name == name {\n\t\t\t\tcommon.Logger(ctx).Debugf(\"Network %v exists\", name)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\n\t\t_, err = cli.NetworkCreate(ctx, name, network.CreateOptions{\n\t\t\tDriver: \"bridge\",\n\t\t\tScope:  \"local\",\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\nfunc NewDockerNetworkRemoveExecutor(name string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tcli, err := GetDockerClient(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer cli.Close()\n\n\t\t// Make sure that all network of the specified name are removed\n\t\t// cli.NetworkRemove refuses to remove a network if there are duplicates\n\t\tnetworks, err := cli.NetworkList(ctx, network.ListOptions{})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcommon.Logger(ctx).Debugf(\"%v\", networks)\n\t\tfor _, net := range networks {\n\t\t\tif net.Name == name {\n\t\t\t\tresult, err := cli.NetworkInspect(ctx, net.ID, network.InspectOptions{})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tif len(result.Containers) == 0 {\n\t\t\t\t\tif err = cli.NetworkRemove(ctx, net.ID); err != nil {\n\t\t\t\t\t\tcommon.Logger(ctx).Debugf(\"%v\", err)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcommon.Logger(ctx).Debugf(\"Refusing to remove network %v because it still has active endpoints\", name)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn err\n\t}\n}\n"
  },
  {
    "path": "pkg/container/docker_pull.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/api/types/registry\"\n\n\t\"github.com/nektos/act/pkg/common\"\n)\n\n// NewDockerPullExecutor function to create a run executor for the container\nfunc NewDockerPullExecutor(input NewDockerPullExecutorInput) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tlogger.Debugf(\"%sdocker pull %v\", logPrefix, input.Image)\n\n\t\tif common.Dryrun(ctx) {\n\t\t\treturn nil\n\t\t}\n\n\t\tpull := input.ForcePull\n\t\tif !pull {\n\t\t\timageExists, err := ImageExistsLocally(ctx, input.Image, input.Platform)\n\t\t\tlogger.Debugf(\"Image exists? %v\", imageExists)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to determine if image already exists for image '%s' (%s): %w\", input.Image, input.Platform, err)\n\t\t\t}\n\n\t\t\tif !imageExists {\n\t\t\t\tpull = true\n\t\t\t}\n\t\t}\n\n\t\tif !pull {\n\t\t\treturn nil\n\t\t}\n\n\t\timageRef := cleanImage(ctx, input.Image)\n\t\tlogger.Debugf(\"pulling image '%v' (%s)\", imageRef, input.Platform)\n\n\t\tcli, err := GetDockerClient(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer cli.Close()\n\n\t\timagePullOptions, err := getImagePullOptions(ctx, input)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treader, err := cli.ImagePull(ctx, imageRef, imagePullOptions)\n\n\t\t_ = logDockerResponse(logger, reader, err != nil)\n\t\tif err != nil {\n\t\t\tif imagePullOptions.RegistryAuth != \"\" && strings.Contains(err.Error(), \"unauthorized\") {\n\t\t\t\tlogger.Errorf(\"pulling image '%v' (%s) failed with credentials %s retrying without them, please check for stale docker config files\", imageRef, input.Platform, err.Error())\n\t\t\t\timagePullOptions.RegistryAuth = \"\"\n\t\t\t\treader, err = cli.ImagePull(ctx, imageRef, imagePullOptions)\n\n\t\t\t\t_ = logDockerResponse(logger, reader, err != nil)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc getImagePullOptions(ctx context.Context, input NewDockerPullExecutorInput) (image.PullOptions, error) {\n\timagePullOptions := image.PullOptions{\n\t\tPlatform: input.Platform,\n\t}\n\tlogger := common.Logger(ctx)\n\n\tif input.Username != \"\" && input.Password != \"\" {\n\t\tlogger.Debugf(\"using authentication for docker pull\")\n\n\t\tauthConfig := registry.AuthConfig{\n\t\t\tUsername: input.Username,\n\t\t\tPassword: input.Password,\n\t\t}\n\n\t\tencodedJSON, err := json.Marshal(authConfig)\n\t\tif err != nil {\n\t\t\treturn imagePullOptions, err\n\t\t}\n\n\t\timagePullOptions.RegistryAuth = base64.URLEncoding.EncodeToString(encodedJSON)\n\t} else {\n\t\tauthConfig, err := LoadDockerAuthConfig(ctx, input.Image)\n\t\tif err != nil {\n\t\t\treturn imagePullOptions, err\n\t\t}\n\t\tif authConfig.Username == \"\" && authConfig.Password == \"\" {\n\t\t\treturn imagePullOptions, nil\n\t\t}\n\t\tlogger.Info(\"using DockerAuthConfig authentication for docker pull\")\n\n\t\tencodedJSON, err := json.Marshal(authConfig)\n\t\tif err != nil {\n\t\t\treturn imagePullOptions, err\n\t\t}\n\n\t\timagePullOptions.RegistryAuth = base64.URLEncoding.EncodeToString(encodedJSON)\n\t}\n\n\treturn imagePullOptions, nil\n}\n\nfunc cleanImage(ctx context.Context, image string) string {\n\tref, err := reference.ParseAnyReference(image)\n\tif err != nil {\n\t\tcommon.Logger(ctx).Error(err)\n\t\treturn \"\"\n\t}\n\n\treturn ref.String()\n}\n"
  },
  {
    "path": "pkg/container/docker_pull_test.go",
    "content": "package container\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/docker/cli/cli/config\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\tassert \"github.com/stretchr/testify/assert\"\n)\n\nfunc init() {\n\tlog.SetLevel(log.DebugLevel)\n}\n\nfunc TestCleanImage(t *testing.T) {\n\ttables := []struct {\n\t\timageIn  string\n\t\timageOut string\n\t}{\n\t\t{\"myhost.com/foo/bar\", \"myhost.com/foo/bar\"},\n\t\t{\"localhost:8000/canonical/ubuntu\", \"localhost:8000/canonical/ubuntu\"},\n\t\t{\"localhost/canonical/ubuntu:latest\", \"localhost/canonical/ubuntu:latest\"},\n\t\t{\"localhost:8000/canonical/ubuntu:latest\", \"localhost:8000/canonical/ubuntu:latest\"},\n\t\t{\"ubuntu\", \"docker.io/library/ubuntu\"},\n\t\t{\"ubuntu:18.04\", \"docker.io/library/ubuntu:18.04\"},\n\t\t{\"cibuilds/hugo:0.53\", \"docker.io/cibuilds/hugo:0.53\"},\n\t}\n\n\tfor _, table := range tables {\n\t\timageOut := cleanImage(context.Background(), table.imageIn)\n\t\tassert.Equal(t, table.imageOut, imageOut)\n\t}\n}\n\nfunc TestGetImagePullOptions(t *testing.T) {\n\tctx := context.Background()\n\n\tconfig.SetDir(\"/non-existent/docker\")\n\n\toptions, err := getImagePullOptions(ctx, NewDockerPullExecutorInput{})\n\tassert.Nil(t, err, \"Failed to create ImagePullOptions\")\n\tassert.Equal(t, \"\", options.RegistryAuth, \"RegistryAuth should be empty if no username or password is set\")\n\n\toptions, err = getImagePullOptions(ctx, NewDockerPullExecutorInput{\n\t\tImage:    \"\",\n\t\tUsername: \"username\",\n\t\tPassword: \"password\",\n\t})\n\tassert.Nil(t, err, \"Failed to create ImagePullOptions\")\n\tassert.Equal(t, \"eyJ1c2VybmFtZSI6InVzZXJuYW1lIiwicGFzc3dvcmQiOiJwYXNzd29yZCJ9\", options.RegistryAuth, \"Username and Password should be provided\")\n\n\tconfig.SetDir(\"testdata/docker-pull-options\")\n\n\toptions, err = getImagePullOptions(ctx, NewDockerPullExecutorInput{\n\t\tImage: \"nektos/act\",\n\t})\n\tassert.Nil(t, err, \"Failed to create ImagePullOptions\")\n\tassert.Equal(t, \"eyJ1c2VybmFtZSI6InVzZXJuYW1lIiwicGFzc3dvcmQiOiJwYXNzd29yZFxuIiwic2VydmVyYWRkcmVzcyI6Imh0dHBzOi8vaW5kZXguZG9ja2VyLmlvL3YxLyJ9\", options.RegistryAuth, \"RegistryAuth should be taken from local docker config\")\n}\n"
  },
  {
    "path": "pkg/container/docker_run.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"dario.cat/mergo\"\n\t\"github.com/Masterminds/semver\"\n\t\"github.com/docker/cli/cli/connhelper\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/mount\"\n\t\"github.com/docker/docker/api/types/network\"\n\t\"github.com/docker/docker/api/types/system\"\n\t\"github.com/docker/docker/client\"\n\t\"github.com/docker/docker/pkg/stdcopy\"\n\t\"github.com/go-git/go-billy/v5/helper/polyfill\"\n\t\"github.com/go-git/go-billy/v5/osfs\"\n\t\"github.com/go-git/go-git/v5/plumbing/format/gitignore\"\n\t\"github.com/joho/godotenv\"\n\t\"github.com/kballard/go-shellquote\"\n\tspecs \"github.com/opencontainers/image-spec/specs-go/v1\"\n\t\"github.com/spf13/pflag\"\n\t\"golang.org/x/term\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/filecollector\"\n)\n\n// NewContainer creates a reference to a container\nfunc NewContainer(input *NewContainerInput) ExecutionsEnvironment {\n\tcr := new(containerReference)\n\tcr.input = input\n\treturn cr\n}\n\n// supportsContainerImagePlatform returns true if the underlying Docker server\n// API version is 1.41 and beyond\nfunc supportsContainerImagePlatform(ctx context.Context, cli client.APIClient) bool {\n\tlogger := common.Logger(ctx)\n\tver, err := cli.ServerVersion(ctx)\n\tif err != nil {\n\t\tlogger.Panicf(\"Failed to get Docker API Version: %s\", err)\n\t\treturn false\n\t}\n\tsv, err := semver.NewVersion(ver.APIVersion)\n\tif err != nil {\n\t\tlogger.Panicf(\"Failed to unmarshal Docker Version: %s\", err)\n\t\treturn false\n\t}\n\tconstraint, _ := semver.NewConstraint(\">= 1.41\")\n\treturn constraint.Check(sv)\n}\n\nfunc (cr *containerReference) Create(capAdd []string, capDrop []string) common.Executor {\n\treturn common.\n\t\tNewInfoExecutor(\"%sdocker create image=%s platform=%s entrypoint=%+q cmd=%+q network=%+q\", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd, cr.input.NetworkMode).\n\t\tThen(\n\t\t\tcommon.NewPipelineExecutor(\n\t\t\t\tcr.connect(),\n\t\t\t\tcr.find(),\n\t\t\t\tcr.create(capAdd, capDrop),\n\t\t\t).IfNot(common.Dryrun),\n\t\t)\n}\n\nfunc (cr *containerReference) Start(attach bool) common.Executor {\n\treturn common.\n\t\tNewInfoExecutor(\"%sdocker run image=%s platform=%s entrypoint=%+q cmd=%+q network=%+q\", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Entrypoint, cr.input.Cmd, cr.input.NetworkMode).\n\t\tThen(\n\t\t\tcommon.NewPipelineExecutor(\n\t\t\t\tcr.connect(),\n\t\t\t\tcr.find(),\n\t\t\t\tcr.attach().IfBool(attach),\n\t\t\t\tcr.start(),\n\t\t\t\tcr.wait().IfBool(attach),\n\t\t\t\tcr.tryReadUID(),\n\t\t\t\tcr.tryReadGID(),\n\t\t\t\tfunc(ctx context.Context) error {\n\t\t\t\t\t// If this fails, then folders have wrong permissions on non root container\n\t\t\t\t\tif cr.UID != 0 || cr.GID != 0 {\n\t\t\t\t\t\t_ = cr.Exec([]string{\"chown\", \"-R\", fmt.Sprintf(\"%d:%d\", cr.UID, cr.GID), cr.input.WorkingDir}, nil, \"0\", \"\")(ctx)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t).IfNot(common.Dryrun),\n\t\t)\n}\n\nfunc (cr *containerReference) Pull(forcePull bool) common.Executor {\n\treturn common.\n\t\tNewInfoExecutor(\"%sdocker pull image=%s platform=%s username=%s forcePull=%t\", logPrefix, cr.input.Image, cr.input.Platform, cr.input.Username, forcePull).\n\t\tThen(\n\t\t\tNewDockerPullExecutor(NewDockerPullExecutorInput{\n\t\t\t\tImage:     cr.input.Image,\n\t\t\t\tForcePull: forcePull,\n\t\t\t\tPlatform:  cr.input.Platform,\n\t\t\t\tUsername:  cr.input.Username,\n\t\t\t\tPassword:  cr.input.Password,\n\t\t\t}),\n\t\t)\n}\n\nfunc (cr *containerReference) Copy(destPath string, files ...*FileEntry) common.Executor {\n\treturn common.NewPipelineExecutor(\n\t\tcr.connect(),\n\t\tcr.find(),\n\t\tcr.copyContent(destPath, files...),\n\t).IfNot(common.Dryrun)\n}\n\nfunc (cr *containerReference) CopyDir(destPath string, srcPath string, useGitIgnore bool) common.Executor {\n\treturn common.NewPipelineExecutor(\n\t\tcommon.NewInfoExecutor(\"%sdocker cp src=%s dst=%s\", logPrefix, srcPath, destPath),\n\t\tcr.copyDir(destPath, srcPath, useGitIgnore),\n\t\tfunc(ctx context.Context) error {\n\t\t\t// If this fails, then folders have wrong permissions on non root container\n\t\t\tif cr.UID != 0 || cr.GID != 0 {\n\t\t\t\t_ = cr.Exec([]string{\"chown\", \"-R\", fmt.Sprintf(\"%d:%d\", cr.UID, cr.GID), destPath}, nil, \"0\", \"\")(ctx)\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t).IfNot(common.Dryrun)\n}\n\nfunc (cr *containerReference) GetContainerArchive(ctx context.Context, srcPath string) (io.ReadCloser, error) {\n\tif common.Dryrun(ctx) {\n\t\treturn nil, fmt.Errorf(\"DRYRUN is not supported in GetContainerArchive\")\n\t}\n\ta, _, err := cr.cli.CopyFromContainer(ctx, cr.id, srcPath)\n\treturn a, err\n}\n\nfunc (cr *containerReference) UpdateFromEnv(srcPath string, env *map[string]string) common.Executor {\n\treturn parseEnvFile(cr, srcPath, env).IfNot(common.Dryrun)\n}\n\nfunc (cr *containerReference) UpdateFromImageEnv(env *map[string]string) common.Executor {\n\treturn cr.extractFromImageEnv(env).IfNot(common.Dryrun)\n}\n\nfunc (cr *containerReference) Exec(command []string, env map[string]string, user, workdir string) common.Executor {\n\treturn common.NewPipelineExecutor(\n\t\tcommon.NewInfoExecutor(\"%sdocker exec cmd=[%s] user=%s workdir=%s\", logPrefix, strings.Join(command, \" \"), user, workdir),\n\t\tcr.connect(),\n\t\tcr.find(),\n\t\tcr.exec(command, env, user, workdir),\n\t).IfNot(common.Dryrun)\n}\n\nfunc (cr *containerReference) Remove() common.Executor {\n\treturn common.NewPipelineExecutor(\n\t\tcr.connect(),\n\t\tcr.find(),\n\t).Finally(\n\t\tcr.remove(),\n\t).IfNot(common.Dryrun)\n}\n\nfunc (cr *containerReference) GetHealth(ctx context.Context) Health {\n\tresp, err := cr.cli.ContainerInspect(ctx, cr.id)\n\tlogger := common.Logger(ctx)\n\tif err != nil {\n\t\tlogger.Errorf(\"failed to query container health %s\", err)\n\t\treturn HealthUnHealthy\n\t}\n\tif resp.Config == nil || resp.Config.Healthcheck == nil || resp.State == nil || resp.State.Health == nil || len(resp.Config.Healthcheck.Test) == 1 && strings.EqualFold(resp.Config.Healthcheck.Test[0], \"NONE\") {\n\t\tlogger.Debugf(\"no container health check defined\")\n\t\treturn HealthHealthy\n\t}\n\n\tlogger.Infof(\"container health of %s (%s) is %s\", cr.id, resp.Config.Image, resp.State.Health.Status)\n\tswitch resp.State.Health.Status {\n\tcase \"starting\":\n\t\treturn HealthStarting\n\tcase \"healthy\":\n\t\treturn HealthHealthy\n\tcase \"unhealthy\":\n\t\treturn HealthUnHealthy\n\t}\n\treturn HealthUnHealthy\n}\n\nfunc (cr *containerReference) ReplaceLogWriter(stdout io.Writer, stderr io.Writer) (io.Writer, io.Writer) {\n\tout := cr.input.Stdout\n\terr := cr.input.Stderr\n\n\tcr.input.Stdout = stdout\n\tcr.input.Stderr = stderr\n\n\treturn out, err\n}\n\ntype containerReference struct {\n\tcli   client.APIClient\n\tid    string\n\tinput *NewContainerInput\n\tUID   int\n\tGID   int\n\tLinuxContainerEnvironmentExtensions\n}\n\nfunc GetDockerClient(ctx context.Context) (cli client.APIClient, err error) {\n\tdockerHost := os.Getenv(\"DOCKER_HOST\")\n\n\tif strings.HasPrefix(dockerHost, \"ssh://\") {\n\t\tvar helper *connhelper.ConnectionHelper\n\n\t\thelper, err = connhelper.GetConnectionHelper(dockerHost)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcli, err = client.NewClientWithOpts(\n\t\t\tclient.WithHost(helper.Host),\n\t\t\tclient.WithDialContext(helper.Dialer),\n\t\t)\n\t} else {\n\t\tcli, err = client.NewClientWithOpts(client.FromEnv)\n\t}\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to connect to docker daemon: %w\", err)\n\t}\n\tcli.NegotiateAPIVersion(ctx)\n\n\treturn cli, nil\n}\n\nfunc GetHostInfo(ctx context.Context) (info system.Info, err error) {\n\tvar cli client.APIClient\n\tcli, err = GetDockerClient(ctx)\n\tif err != nil {\n\t\treturn info, err\n\t}\n\tdefer cli.Close()\n\n\tinfo, err = cli.Info(ctx)\n\tif err != nil {\n\t\treturn info, err\n\t}\n\n\treturn info, nil\n}\n\n// Arch fetches values from docker info and translates architecture to\n// GitHub actions compatible runner.arch values\n// https://github.com/github/docs/blob/main/data/reusables/actions/runner-arch-description.md\nfunc RunnerArch(ctx context.Context) string {\n\tinfo, err := GetHostInfo(ctx)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\tarchMapper := map[string]string{\n\t\t\"x86_64\":  \"X64\",\n\t\t\"amd64\":   \"X64\",\n\t\t\"386\":     \"X86\",\n\t\t\"aarch64\": \"ARM64\",\n\t\t\"arm64\":   \"ARM64\",\n\t}\n\tif arch, ok := archMapper[info.Architecture]; ok {\n\t\treturn arch\n\t}\n\treturn info.Architecture\n}\n\nfunc (cr *containerReference) connect() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tif cr.cli != nil {\n\t\t\treturn nil\n\t\t}\n\t\tcli, err := GetDockerClient(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcr.cli = cli\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) Close() common.Executor {\n\treturn func(_ context.Context) error {\n\t\tif cr.cli != nil {\n\t\t\terr := cr.cli.Close()\n\t\t\tcr.cli = nil\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to close client: %w\", err)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) find() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tif cr.id != \"\" {\n\t\t\treturn nil\n\t\t}\n\t\tcontainers, err := cr.cli.ContainerList(ctx, container.ListOptions{\n\t\t\tAll: true,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to list containers: %w\", err)\n\t\t}\n\n\t\tfor _, c := range containers {\n\t\t\tfor _, name := range c.Names {\n\t\t\t\tif name[1:] == cr.input.Name {\n\t\t\t\t\tcr.id = c.ID\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tcr.id = \"\"\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) remove() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tif cr.id == \"\" {\n\t\t\treturn nil\n\t\t}\n\n\t\tlogger := common.Logger(ctx)\n\t\terr := cr.cli.ContainerRemove(ctx, cr.id, container.RemoveOptions{\n\t\t\tRemoveVolumes: true,\n\t\t\tForce:         true,\n\t\t})\n\t\tif err != nil {\n\t\t\tlogger.Error(fmt.Errorf(\"failed to remove container: %w\", err))\n\t\t}\n\n\t\tlogger.Debugf(\"Removed container: %v\", cr.id)\n\t\tcr.id = \"\"\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) mergeContainerConfigs(ctx context.Context, config *container.Config, hostConfig *container.HostConfig) (*container.Config, *container.HostConfig, error) {\n\tlogger := common.Logger(ctx)\n\tinput := cr.input\n\n\tif input.Options == \"\" {\n\t\treturn config, hostConfig, nil\n\t}\n\n\t// parse configuration from CLI container.options\n\tflags := pflag.NewFlagSet(\"container_flags\", pflag.ContinueOnError)\n\tcopts := addFlags(flags)\n\n\toptionsArgs, err := shellquote.Split(input.Options)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Cannot split container options: '%s': '%w'\", input.Options, err)\n\t}\n\n\terr = flags.Parse(optionsArgs)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Cannot parse container options: '%s': '%w'\", input.Options, err)\n\t}\n\n\tif len(copts.netMode.Value()) == 0 {\n\t\tif err = copts.netMode.Set(cr.input.NetworkMode); err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"Cannot parse networkmode=%s. This is an internal error and should not happen: '%w'\", cr.input.NetworkMode, err)\n\t\t}\n\t}\n\n\tcontainerConfig, err := parse(flags, copts, runtime.GOOS)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Cannot process container options: '%s': '%w'\", input.Options, err)\n\t}\n\n\tlogger.Debugf(\"Custom container.Config from options ==> %+v\", containerConfig.Config)\n\n\terr = mergo.Merge(config, containerConfig.Config, mergo.WithOverride)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Cannot merge container.Config options: '%s': '%w'\", input.Options, err)\n\t}\n\tlogger.Debugf(\"Merged container.Config ==> %+v\", config)\n\n\tlogger.Debugf(\"Custom container.HostConfig from options ==> %+v\", containerConfig.HostConfig)\n\n\thostConfig.Binds = append(hostConfig.Binds, containerConfig.HostConfig.Binds...)\n\thostConfig.Mounts = append(hostConfig.Mounts, containerConfig.HostConfig.Mounts...)\n\tbinds := hostConfig.Binds\n\tmounts := hostConfig.Mounts\n\terr = mergo.Merge(hostConfig, containerConfig.HostConfig, mergo.WithOverride)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Cannot merge container.HostConfig options: '%s': '%w'\", input.Options, err)\n\t}\n\thostConfig.Binds = binds\n\thostConfig.Mounts = mounts\n\tlogger.Debugf(\"Merged container.HostConfig ==> %+v\", hostConfig)\n\n\treturn config, hostConfig, nil\n}\n\nfunc (cr *containerReference) create(capAdd []string, capDrop []string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tif cr.id != \"\" {\n\t\t\treturn nil\n\t\t}\n\t\tlogger := common.Logger(ctx)\n\t\tisTerminal := term.IsTerminal(int(os.Stdout.Fd()))\n\t\tinput := cr.input\n\n\t\tconfig := &container.Config{\n\t\t\tImage:        input.Image,\n\t\t\tWorkingDir:   input.WorkingDir,\n\t\t\tEnv:          input.Env,\n\t\t\tExposedPorts: input.ExposedPorts,\n\t\t\tTty:          isTerminal,\n\t\t}\n\t\tlogger.Debugf(\"Common container.Config ==> %+v\", config)\n\n\t\tif len(input.Cmd) != 0 {\n\t\t\tconfig.Cmd = input.Cmd\n\t\t}\n\n\t\tif len(input.Entrypoint) != 0 {\n\t\t\tconfig.Entrypoint = input.Entrypoint\n\t\t}\n\n\t\tmounts := make([]mount.Mount, 0)\n\t\tfor mountSource, mountTarget := range input.Mounts {\n\t\t\tmounts = append(mounts, mount.Mount{\n\t\t\t\tType:   mount.TypeVolume,\n\t\t\t\tSource: mountSource,\n\t\t\t\tTarget: mountTarget,\n\t\t\t})\n\t\t}\n\n\t\tvar platSpecs *specs.Platform\n\t\tif supportsContainerImagePlatform(ctx, cr.cli) && cr.input.Platform != \"\" {\n\t\t\tdesiredPlatform := strings.SplitN(cr.input.Platform, `/`, 2)\n\n\t\t\tif len(desiredPlatform) != 2 {\n\t\t\t\treturn fmt.Errorf(\"incorrect container platform option '%s'\", cr.input.Platform)\n\t\t\t}\n\n\t\t\tplatSpecs = &specs.Platform{\n\t\t\t\tArchitecture: desiredPlatform[1],\n\t\t\t\tOS:           desiredPlatform[0],\n\t\t\t}\n\t\t}\n\n\t\thostConfig := &container.HostConfig{\n\t\t\tCapAdd:       capAdd,\n\t\t\tCapDrop:      capDrop,\n\t\t\tBinds:        input.Binds,\n\t\t\tMounts:       mounts,\n\t\t\tNetworkMode:  container.NetworkMode(input.NetworkMode),\n\t\t\tPrivileged:   input.Privileged,\n\t\t\tUsernsMode:   container.UsernsMode(input.UsernsMode),\n\t\t\tPortBindings: input.PortBindings,\n\t\t}\n\t\tlogger.Debugf(\"Common container.HostConfig ==> %+v\", hostConfig)\n\n\t\tconfig, hostConfig, err := cr.mergeContainerConfigs(ctx, config, hostConfig)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvar networkingConfig *network.NetworkingConfig\n\t\tlogger.Debugf(\"input.NetworkAliases ==> %v\", input.NetworkAliases)\n\t\tn := hostConfig.NetworkMode\n\t\t// IsUserDefined and IsHost are broken on windows\n\t\tif n.IsUserDefined() && n != \"host\" && len(input.NetworkAliases) > 0 {\n\t\t\tendpointConfig := &network.EndpointSettings{\n\t\t\t\tAliases: input.NetworkAliases,\n\t\t\t}\n\t\t\tnetworkingConfig = &network.NetworkingConfig{\n\t\t\t\tEndpointsConfig: map[string]*network.EndpointSettings{\n\t\t\t\t\tinput.NetworkMode: endpointConfig,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tresp, err := cr.cli.ContainerCreate(ctx, config, hostConfig, networkingConfig, platSpecs, input.Name)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create container: '%w'\", err)\n\t\t}\n\n\t\tlogger.Debugf(\"Created container name=%s id=%v from image %v (platform: %s)\", input.Name, resp.ID, input.Image, input.Platform)\n\t\tlogger.Debugf(\"ENV ==> %v\", input.Env)\n\n\t\tcr.id = resp.ID\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) extractFromImageEnv(env *map[string]string) common.Executor {\n\tenvMap := *env\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\n\t\tinspect, err := cr.cli.ImageInspect(ctx, cr.input.Image)\n\t\tif err != nil {\n\t\t\tlogger.Error(err)\n\t\t\treturn fmt.Errorf(\"inspect image: %w\", err)\n\t\t}\n\n\t\tif inspect.Config == nil {\n\t\t\treturn nil\n\t\t}\n\n\t\timageEnv, err := godotenv.Unmarshal(strings.Join(inspect.Config.Env, \"\\n\"))\n\t\tif err != nil {\n\t\t\tlogger.Error(err)\n\t\t\treturn fmt.Errorf(\"unmarshal image env: %w\", err)\n\t\t}\n\n\t\tfor k, v := range imageEnv {\n\t\t\tif k == \"PATH\" {\n\t\t\t\tif envMap[k] == \"\" {\n\t\t\t\t\tenvMap[k] = v\n\t\t\t\t} else {\n\t\t\t\t\tenvMap[k] += `:` + v\n\t\t\t\t}\n\t\t\t} else if envMap[k] == \"\" {\n\t\t\t\tenvMap[k] = v\n\t\t\t}\n\t\t}\n\n\t\tenv = &envMap\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) exec(cmd []string, env map[string]string, user, workdir string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\t// Fix slashes when running on Windows\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\tvar newCmd []string\n\t\t\tfor _, v := range cmd {\n\t\t\t\tnewCmd = append(newCmd, strings.ReplaceAll(v, `\\`, `/`))\n\t\t\t}\n\t\t\tcmd = newCmd\n\t\t}\n\n\t\tlogger.Debugf(\"Exec command '%s'\", cmd)\n\t\tisTerminal := term.IsTerminal(int(os.Stdout.Fd()))\n\t\tenvList := make([]string, 0)\n\t\tfor k, v := range env {\n\t\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", k, v))\n\t\t}\n\n\t\tvar wd string\n\t\tif workdir != \"\" {\n\t\t\tif strings.HasPrefix(workdir, \"/\") {\n\t\t\t\twd = workdir\n\t\t\t} else {\n\t\t\t\twd = fmt.Sprintf(\"%s/%s\", cr.input.WorkingDir, workdir)\n\t\t\t}\n\t\t} else {\n\t\t\twd = cr.input.WorkingDir\n\t\t}\n\t\tlogger.Debugf(\"Working directory '%s'\", wd)\n\n\t\tidResp, err := cr.cli.ContainerExecCreate(ctx, cr.id, container.ExecOptions{\n\t\t\tUser:         user,\n\t\t\tCmd:          cmd,\n\t\t\tWorkingDir:   wd,\n\t\t\tEnv:          envList,\n\t\t\tTty:          isTerminal,\n\t\t\tAttachStderr: true,\n\t\t\tAttachStdout: true,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create exec: %w\", err)\n\t\t}\n\n\t\tresp, err := cr.cli.ContainerExecAttach(ctx, idResp.ID, container.ExecStartOptions{\n\t\t\tTty: isTerminal,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to attach to exec: %w\", err)\n\t\t}\n\t\tdefer resp.Close()\n\n\t\terr = cr.waitForCommand(ctx, isTerminal, resp)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tinspectResp, err := cr.cli.ContainerExecInspect(ctx, idResp.ID)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to inspect exec: %w\", err)\n\t\t}\n\n\t\tswitch inspectResp.ExitCode {\n\t\tcase 0:\n\t\t\treturn nil\n\t\tcase 127:\n\t\t\treturn fmt.Errorf(\"exitcode '%d': command not found, please refer to https://github.com/nektos/act/issues/107 for more information\", inspectResp.ExitCode)\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"exitcode '%d': failure\", inspectResp.ExitCode)\n\t\t}\n\t}\n}\n\nfunc (cr *containerReference) tryReadID(opt string, cbk func(id int)) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tidResp, err := cr.cli.ContainerExecCreate(ctx, cr.id, container.ExecOptions{\n\t\t\tCmd:          []string{\"id\", opt},\n\t\t\tAttachStdout: true,\n\t\t\tAttachStderr: true,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tresp, err := cr.cli.ContainerExecAttach(ctx, idResp.ID, container.ExecStartOptions{})\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tdefer resp.Close()\n\n\t\tsid, err := resp.Reader.ReadString('\\n')\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\texp := regexp.MustCompile(`\\d+\\n`)\n\t\tfound := exp.FindString(sid)\n\t\tid, err := strconv.ParseInt(strings.TrimSpace(found), 10, 32)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tcbk(int(id))\n\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) tryReadUID() common.Executor {\n\treturn cr.tryReadID(\"-u\", func(id int) { cr.UID = id })\n}\n\nfunc (cr *containerReference) tryReadGID() common.Executor {\n\treturn cr.tryReadID(\"-g\", func(id int) { cr.GID = id })\n}\n\nfunc (cr *containerReference) waitForCommand(ctx context.Context, isTerminal bool, resp types.HijackedResponse) error {\n\tlogger := common.Logger(ctx)\n\n\tcmdResponse := make(chan error)\n\n\tgo func() {\n\t\tvar outWriter io.Writer\n\t\toutWriter = cr.input.Stdout\n\t\tif outWriter == nil {\n\t\t\toutWriter = os.Stdout\n\t\t}\n\t\terrWriter := cr.input.Stderr\n\t\tif errWriter == nil {\n\t\t\terrWriter = os.Stderr\n\t\t}\n\n\t\tvar err error\n\t\tif !isTerminal || os.Getenv(\"NORAW\") != \"\" {\n\t\t\t_, err = stdcopy.StdCopy(outWriter, errWriter, resp.Reader)\n\t\t} else {\n\t\t\t_, err = io.Copy(outWriter, resp.Reader)\n\t\t}\n\t\tcmdResponse <- err\n\t}()\n\n\tselect {\n\tcase <-ctx.Done():\n\t\t// send ctrl + c\n\t\t_, err := resp.Conn.Write([]byte{3})\n\t\tif err != nil {\n\t\t\tlogger.Warnf(\"Failed to send CTRL+C: %+s\", err)\n\t\t}\n\n\t\t// we return the context canceled error to prevent other steps\n\t\t// from executing\n\t\treturn ctx.Err()\n\tcase err := <-cmdResponse:\n\t\tif err != nil {\n\t\t\tlogger.Error(err)\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error {\n\tif common.Dryrun(ctx) {\n\t\treturn nil\n\t}\n\t// Mkdir\n\tbuf := &bytes.Buffer{}\n\ttw := tar.NewWriter(buf)\n\t_ = tw.WriteHeader(&tar.Header{\n\t\tName:     destPath,\n\t\tMode:     0o777,\n\t\tTypeflag: tar.TypeDir,\n\t})\n\ttw.Close()\n\terr := cr.cli.CopyToContainer(ctx, cr.id, \"/\", buf, container.CopyToContainerOptions{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to mkdir to copy content to container: %w\", err)\n\t}\n\t// Copy Content\n\terr = cr.cli.CopyToContainer(ctx, cr.id, destPath, tarStream, container.CopyToContainerOptions{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to copy content to container: %w\", err)\n\t}\n\t// If this fails, then folders have wrong permissions on non root container\n\tif cr.UID != 0 || cr.GID != 0 {\n\t\t_ = cr.Exec([]string{\"chown\", \"-R\", fmt.Sprintf(\"%d:%d\", cr.UID, cr.GID), destPath}, nil, \"0\", \"\")(ctx)\n\t}\n\treturn nil\n}\n\nfunc (cr *containerReference) copyDir(dstPath string, srcPath string, useGitIgnore bool) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\ttarFile, err := os.CreateTemp(\"\", \"act\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlogger.Debugf(\"Writing tarball %s from %s\", tarFile.Name(), srcPath)\n\t\tdefer func(tarFile *os.File) {\n\t\t\tname := tarFile.Name()\n\t\t\terr := tarFile.Close()\n\t\t\tif !errors.Is(err, os.ErrClosed) {\n\t\t\t\tlogger.Error(err)\n\t\t\t}\n\t\t\terr = os.Remove(name)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Error(err)\n\t\t\t}\n\t\t}(tarFile)\n\t\ttw := tar.NewWriter(tarFile)\n\n\t\tsrcPrefix := filepath.Dir(srcPath)\n\t\tif !strings.HasSuffix(srcPrefix, string(filepath.Separator)) {\n\t\t\tsrcPrefix += string(filepath.Separator)\n\t\t}\n\t\tlogger.Debugf(\"Stripping prefix:%s src:%s\", srcPrefix, srcPath)\n\n\t\tvar ignorer gitignore.Matcher\n\t\tif useGitIgnore {\n\t\t\tps, err := gitignore.ReadPatterns(polyfill.New(osfs.New(srcPath)), nil)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Debugf(\"Error loading .gitignore: %v\", err)\n\t\t\t}\n\n\t\t\tignorer = gitignore.NewMatcher(ps)\n\t\t}\n\n\t\tfc := &filecollector.FileCollector{\n\t\t\tFs:        &filecollector.DefaultFs{},\n\t\t\tIgnorer:   ignorer,\n\t\t\tSrcPath:   srcPath,\n\t\t\tSrcPrefix: srcPrefix,\n\t\t\tHandler: &filecollector.TarCollector{\n\t\t\t\tTarWriter: tw,\n\t\t\t\tUID:       cr.UID,\n\t\t\t\tGID:       cr.GID,\n\t\t\t\tDstDir:    dstPath[1:],\n\t\t\t},\n\t\t}\n\n\t\terr = filepath.Walk(srcPath, fc.CollectFiles(ctx, []string{}))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := tw.Close(); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tlogger.Debugf(\"Extracting content from '%s' to '%s'\", tarFile.Name(), dstPath)\n\t\t_, err = tarFile.Seek(0, 0)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to seek tar archive: %w\", err)\n\t\t}\n\t\terr = cr.cli.CopyToContainer(ctx, cr.id, \"/\", tarFile, container.CopyToContainerOptions{})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to copy content to container: %w\", err)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) copyContent(dstPath string, files ...*FileEntry) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tvar buf bytes.Buffer\n\t\ttw := tar.NewWriter(&buf)\n\t\tfor _, file := range files {\n\t\t\tlogger.Debugf(\"Writing entry to tarball %s len:%d\", file.Name, len(file.Body))\n\t\t\thdr := &tar.Header{\n\t\t\t\tName: file.Name,\n\t\t\t\tMode: int64(file.Mode),\n\t\t\t\tSize: int64(len(file.Body)),\n\t\t\t\tUid:  cr.UID,\n\t\t\t\tGid:  cr.GID,\n\t\t\t}\n\t\t\tif err := tw.WriteHeader(hdr); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif _, err := tw.Write([]byte(file.Body)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err := tw.Close(); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tlogger.Debugf(\"Extracting content to '%s'\", dstPath)\n\t\terr := cr.cli.CopyToContainer(ctx, cr.id, dstPath, &buf, container.CopyToContainerOptions{})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to copy content to container: %w\", err)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) attach() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tout, err := cr.cli.ContainerAttach(ctx, cr.id, container.AttachOptions{\n\t\t\tStream: true,\n\t\t\tStdout: true,\n\t\t\tStderr: true,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to attach to container: %w\", err)\n\t\t}\n\t\tisTerminal := term.IsTerminal(int(os.Stdout.Fd()))\n\n\t\tvar outWriter io.Writer\n\t\toutWriter = cr.input.Stdout\n\t\tif outWriter == nil {\n\t\t\toutWriter = os.Stdout\n\t\t}\n\t\terrWriter := cr.input.Stderr\n\t\tif errWriter == nil {\n\t\t\terrWriter = os.Stderr\n\t\t}\n\t\tgo func() {\n\t\t\tif !isTerminal || os.Getenv(\"NORAW\") != \"\" {\n\t\t\t\t_, err = stdcopy.StdCopy(outWriter, errWriter, out.Reader)\n\t\t\t} else {\n\t\t\t\t_, err = io.Copy(outWriter, out.Reader)\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\tcommon.Logger(ctx).Error(err)\n\t\t\t}\n\t\t}()\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) start() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tlogger.Debugf(\"Starting container: %v\", cr.id)\n\n\t\tif err := cr.cli.ContainerStart(ctx, cr.id, container.StartOptions{}); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to start container: %w\", err)\n\t\t}\n\n\t\tlogger.Debugf(\"Started container: %v\", cr.id)\n\t\treturn nil\n\t}\n}\n\nfunc (cr *containerReference) wait() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tstatusCh, errCh := cr.cli.ContainerWait(ctx, cr.id, container.WaitConditionNotRunning)\n\t\tvar statusCode int64\n\t\tselect {\n\t\tcase err := <-errCh:\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to wait for container: %w\", err)\n\t\t\t}\n\t\tcase status := <-statusCh:\n\t\t\tstatusCode = status.StatusCode\n\t\t}\n\n\t\tlogger.Debugf(\"Return status: %v\", statusCode)\n\n\t\tif statusCode == 0 {\n\t\t\treturn nil\n\t\t}\n\n\t\treturn fmt.Errorf(\"exit with `FAILURE`: %v\", statusCode)\n\t}\n}\n"
  },
  {
    "path": "pkg/container/docker_run_test.go",
    "content": "package container\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/client\"\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n)\n\nfunc TestDocker(t *testing.T) {\n\tctx := context.Background()\n\tclient, err := GetDockerClient(ctx)\n\tassert.NoError(t, err)\n\tdefer client.Close()\n\n\tdockerBuild := NewDockerBuildExecutor(NewDockerBuildExecutorInput{\n\t\tContextDir: \"testdata\",\n\t\tImageTag:   \"envmergetest\",\n\t})\n\n\terr = dockerBuild(ctx)\n\tassert.NoError(t, err)\n\n\tcr := &containerReference{\n\t\tcli: client,\n\t\tinput: &NewContainerInput{\n\t\t\tImage: \"envmergetest\",\n\t\t},\n\t}\n\tenv := map[string]string{\n\t\t\"PATH\":         \"/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin\",\n\t\t\"RANDOM_VAR\":   \"WITH_VALUE\",\n\t\t\"ANOTHER_VAR\":  \"\",\n\t\t\"CONFLICT_VAR\": \"I_EXIST_IN_MULTIPLE_PLACES\",\n\t}\n\n\tenvExecutor := cr.extractFromImageEnv(&env)\n\terr = envExecutor(ctx)\n\tassert.NoError(t, err)\n\tassert.Equal(t, map[string]string{\n\t\t\"PATH\":            \"/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin:/this/path/does/not/exists/anywhere:/this/either\",\n\t\t\"RANDOM_VAR\":      \"WITH_VALUE\",\n\t\t\"ANOTHER_VAR\":     \"\",\n\t\t\"SOME_RANDOM_VAR\": \"\",\n\t\t\"ANOTHER_ONE\":     \"BUT_I_HAVE_VALUE\",\n\t\t\"CONFLICT_VAR\":    \"I_EXIST_IN_MULTIPLE_PLACES\",\n\t}, env)\n}\n\ntype mockDockerClient struct {\n\tclient.APIClient\n\tmock.Mock\n}\n\nfunc (m *mockDockerClient) ContainerExecCreate(ctx context.Context, id string, opts container.ExecOptions) (container.ExecCreateResponse, error) {\n\targs := m.Called(ctx, id, opts)\n\treturn args.Get(0).(container.ExecCreateResponse), args.Error(1)\n}\n\nfunc (m *mockDockerClient) ContainerExecAttach(ctx context.Context, id string, opts container.ExecStartOptions) (types.HijackedResponse, error) {\n\targs := m.Called(ctx, id, opts)\n\treturn args.Get(0).(types.HijackedResponse), args.Error(1)\n}\n\nfunc (m *mockDockerClient) ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error) {\n\targs := m.Called(ctx, execID)\n\treturn args.Get(0).(container.ExecInspect), args.Error(1)\n}\n\nfunc (m *mockDockerClient) CopyToContainer(ctx context.Context, id string, path string, content io.Reader, options container.CopyToContainerOptions) error {\n\targs := m.Called(ctx, id, path, content, options)\n\treturn args.Error(0)\n}\n\ntype endlessReader struct {\n\tio.Reader\n}\n\nfunc (r endlessReader) Read(_ []byte) (n int, err error) {\n\treturn 1, nil\n}\n\ntype mockConn struct {\n\tnet.Conn\n\tmock.Mock\n}\n\nfunc (m *mockConn) Write(b []byte) (n int, err error) {\n\targs := m.Called(b)\n\treturn args.Int(0), args.Error(1)\n}\n\nfunc (m *mockConn) Close() (err error) {\n\treturn nil\n}\n\nfunc TestDockerExecAbort(t *testing.T) {\n\tctx, cancel := context.WithCancel(context.Background())\n\n\tconn := &mockConn{}\n\tconn.On(\"Write\", mock.AnythingOfType(\"[]uint8\")).Return(1, nil)\n\n\tclient := &mockDockerClient{}\n\tclient.On(\"ContainerExecCreate\", ctx, \"123\", mock.AnythingOfType(\"container.ExecOptions\")).Return(container.ExecCreateResponse{ID: \"id\"}, nil)\n\tclient.On(\"ContainerExecAttach\", ctx, \"id\", mock.AnythingOfType(\"container.ExecStartOptions\")).Return(types.HijackedResponse{\n\t\tConn:   conn,\n\t\tReader: bufio.NewReader(endlessReader{}),\n\t}, nil)\n\n\tcr := &containerReference{\n\t\tid:  \"123\",\n\t\tcli: client,\n\t\tinput: &NewContainerInput{\n\t\t\tImage: \"image\",\n\t\t},\n\t}\n\n\tchannel := make(chan error)\n\n\tgo func() {\n\t\tchannel <- cr.exec([]string{\"\"}, map[string]string{}, \"user\", \"workdir\")(ctx)\n\t}()\n\n\ttime.Sleep(500 * time.Millisecond)\n\n\tcancel()\n\n\terr := <-channel\n\tassert.ErrorIs(t, err, context.Canceled)\n\n\tconn.AssertExpectations(t)\n\tclient.AssertExpectations(t)\n}\n\nfunc TestDockerExecFailure(t *testing.T) {\n\tctx := context.Background()\n\n\tconn := &mockConn{}\n\n\tclient := &mockDockerClient{}\n\tclient.On(\"ContainerExecCreate\", ctx, \"123\", mock.AnythingOfType(\"container.ExecOptions\")).Return(container.ExecCreateResponse{ID: \"id\"}, nil)\n\tclient.On(\"ContainerExecAttach\", ctx, \"id\", mock.AnythingOfType(\"container.ExecStartOptions\")).Return(types.HijackedResponse{\n\t\tConn:   conn,\n\t\tReader: bufio.NewReader(strings.NewReader(\"output\")),\n\t}, nil)\n\tclient.On(\"ContainerExecInspect\", ctx, \"id\").Return(container.ExecInspect{\n\t\tExitCode: 1,\n\t}, nil)\n\n\tcr := &containerReference{\n\t\tid:  \"123\",\n\t\tcli: client,\n\t\tinput: &NewContainerInput{\n\t\t\tImage: \"image\",\n\t\t},\n\t}\n\n\terr := cr.exec([]string{\"\"}, map[string]string{}, \"user\", \"workdir\")(ctx)\n\tassert.Error(t, err, \"exit with `FAILURE`: 1\")\n\n\tconn.AssertExpectations(t)\n\tclient.AssertExpectations(t)\n}\n\nfunc TestDockerCopyTarStream(t *testing.T) {\n\tctx := context.Background()\n\n\tconn := &mockConn{}\n\n\tclient := &mockDockerClient{}\n\tclient.On(\"CopyToContainer\", ctx, \"123\", \"/\", mock.Anything, mock.AnythingOfType(\"container.CopyToContainerOptions\")).Return(nil)\n\tclient.On(\"CopyToContainer\", ctx, \"123\", \"/var/run/act\", mock.Anything, mock.AnythingOfType(\"container.CopyToContainerOptions\")).Return(nil)\n\tcr := &containerReference{\n\t\tid:  \"123\",\n\t\tcli: client,\n\t\tinput: &NewContainerInput{\n\t\t\tImage: \"image\",\n\t\t},\n\t}\n\n\t_ = cr.CopyTarStream(ctx, \"/var/run/act\", &bytes.Buffer{})\n\n\tconn.AssertExpectations(t)\n\tclient.AssertExpectations(t)\n}\n\nfunc TestDockerCopyTarStreamDryRun(t *testing.T) {\n\tctx := common.WithDryrun(context.Background(), true)\n\n\tconn := &mockConn{}\n\n\tclient := &mockDockerClient{}\n\tclient.AssertNotCalled(t, \"CopyToContainer\", ctx, \"123\", \"/\", mock.Anything, mock.AnythingOfType(\"container.CopyToContainerOptions\"))\n\tclient.AssertNotCalled(t, \"CopyToContainer\", ctx, \"123\", \"/var/run/act\", mock.Anything, mock.AnythingOfType(\"container.CopyToContainerOptions\"))\n\tcr := &containerReference{\n\t\tid:  \"123\",\n\t\tcli: client,\n\t\tinput: &NewContainerInput{\n\t\t\tImage: \"image\",\n\t\t},\n\t}\n\n\t_ = cr.CopyTarStream(ctx, \"/var/run/act\", &bytes.Buffer{})\n\n\tconn.AssertExpectations(t)\n\tclient.AssertExpectations(t)\n}\n\nfunc TestDockerCopyTarStreamErrorInCopyFiles(t *testing.T) {\n\tctx := context.Background()\n\n\tconn := &mockConn{}\n\n\tmerr := fmt.Errorf(\"Failure\")\n\n\tclient := &mockDockerClient{}\n\tclient.On(\"CopyToContainer\", ctx, \"123\", \"/\", mock.Anything, mock.AnythingOfType(\"container.CopyToContainerOptions\")).Return(merr)\n\tclient.On(\"CopyToContainer\", ctx, \"123\", \"/\", mock.Anything, mock.AnythingOfType(\"container.CopyToContainerOptions\")).Return(merr)\n\tcr := &containerReference{\n\t\tid:  \"123\",\n\t\tcli: client,\n\t\tinput: &NewContainerInput{\n\t\t\tImage: \"image\",\n\t\t},\n\t}\n\n\terr := cr.CopyTarStream(ctx, \"/var/run/act\", &bytes.Buffer{})\n\tassert.ErrorIs(t, err, merr)\n\n\tconn.AssertExpectations(t)\n\tclient.AssertExpectations(t)\n}\n\nfunc TestDockerCopyTarStreamErrorInMkdir(t *testing.T) {\n\tctx := context.Background()\n\n\tconn := &mockConn{}\n\n\tmerr := fmt.Errorf(\"Failure\")\n\n\tclient := &mockDockerClient{}\n\tclient.On(\"CopyToContainer\", ctx, \"123\", \"/\", mock.Anything, mock.AnythingOfType(\"container.CopyToContainerOptions\")).Return(nil)\n\tclient.On(\"CopyToContainer\", ctx, \"123\", \"/var/run/act\", mock.Anything, mock.AnythingOfType(\"container.CopyToContainerOptions\")).Return(merr)\n\tcr := &containerReference{\n\t\tid:  \"123\",\n\t\tcli: client,\n\t\tinput: &NewContainerInput{\n\t\t\tImage: \"image\",\n\t\t},\n\t}\n\n\terr := cr.CopyTarStream(ctx, \"/var/run/act\", &bytes.Buffer{})\n\tassert.ErrorIs(t, err, merr)\n\n\tconn.AssertExpectations(t)\n\tclient.AssertExpectations(t)\n}\n\n// Type assert containerReference implements ExecutionsEnvironment\nvar _ ExecutionsEnvironment = &containerReference{}\n"
  },
  {
    "path": "pkg/container/docker_socket.go",
    "content": "package container\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar CommonSocketLocations = []string{\n\t\"/var/run/docker.sock\",\n\t\"/run/podman/podman.sock\",\n\t\"$HOME/.colima/docker.sock\",\n\t\"$XDG_RUNTIME_DIR/docker.sock\",\n\t\"$XDG_RUNTIME_DIR/podman/podman.sock\",\n\t`\\\\.\\pipe\\docker_engine`,\n\t\"$HOME/.docker/run/docker.sock\",\n}\n\n// returns socket URI or false if not found any\nfunc socketLocation() (string, bool) {\n\tif dockerHost, exists := os.LookupEnv(\"DOCKER_HOST\"); exists {\n\t\treturn dockerHost, true\n\t}\n\n\tfor _, p := range CommonSocketLocations {\n\t\tif _, err := os.Lstat(os.ExpandEnv(p)); err == nil {\n\t\t\tif strings.HasPrefix(p, `\\\\.\\`) {\n\t\t\t\treturn \"npipe://\" + filepath.ToSlash(os.ExpandEnv(p)), true\n\t\t\t}\n\t\t\treturn \"unix://\" + filepath.ToSlash(os.ExpandEnv(p)), true\n\t\t}\n\t}\n\n\treturn \"\", false\n}\n\n// This function, `isDockerHostURI`, takes a string argument `daemonPath`. It checks if the\n// `daemonPath` is a valid Docker host URI. It does this by checking if the scheme of the URI (the\n// part before \"://\") contains only alphabetic characters. If it does, the function returns true,\n// indicating that the `daemonPath` is a Docker host URI. If it doesn't, or if the \"://\" delimiter\n// is not found in the `daemonPath`, the function returns false.\nfunc isDockerHostURI(daemonPath string) bool {\n\tif protoIndex := strings.Index(daemonPath, \"://\"); protoIndex != -1 {\n\t\tscheme := daemonPath[:protoIndex]\n\t\tif strings.IndexFunc(scheme, func(r rune) bool {\n\t\t\treturn (r < 'a' || r > 'z') && (r < 'A' || r > 'Z')\n\t\t}) == -1 {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype SocketAndHost struct {\n\tSocket string\n\tHost   string\n}\n\nfunc GetSocketAndHost(containerSocket string) (SocketAndHost, error) {\n\tlog.Debugf(\"Handling container host and socket\")\n\n\t// Prefer DOCKER_HOST, don't override it\n\tdockerHost, hasDockerHost := socketLocation()\n\tsocketHost := SocketAndHost{Socket: containerSocket, Host: dockerHost}\n\n\t// ** socketHost.Socket cases **\n\t// Case 1: User does _not_ want to mount a daemon socket (passes a dash)\n\t// Case 2: User passes a filepath to the socket; is that even valid?\n\t// Case 3: User passes a valid socket; do nothing\n\t// Case 4: User omitted the flag; set a sane default\n\n\t// ** DOCKER_HOST cases **\n\t// Case A: DOCKER_HOST is set; use it, i.e. do nothing\n\t// Case B: DOCKER_HOST is empty; use sane defaults\n\n\t// Set host for sanity's sake, when the socket isn't useful\n\tif !hasDockerHost && (socketHost.Socket == \"-\" || !isDockerHostURI(socketHost.Socket) || socketHost.Socket == \"\") {\n\t\t// Cases: 1B, 2B, 4B\n\t\tsocket, found := socketLocation()\n\t\tsocketHost.Host = socket\n\t\thasDockerHost = found\n\t}\n\n\t// A - (dash) in socketHost.Socket means don't mount, preserve this value\n\t// otherwise if socketHost.Socket is a filepath don't use it as socket\n\t// Exit early if we're in an invalid state (e.g. when no DOCKER_HOST and user supplied \"-\", a dash or omitted)\n\tif !hasDockerHost && socketHost.Socket != \"\" && !isDockerHostURI(socketHost.Socket) {\n\t\t// Cases: 1B, 2B\n\t\t// Should we early-exit here, since there is no host nor socket to talk to?\n\t\treturn SocketAndHost{}, fmt.Errorf(\"DOCKER_HOST was not set, couldn't be found in the usual locations, and the container daemon socket ('%s') is invalid\", socketHost.Socket)\n\t}\n\n\t// Default to DOCKER_HOST if set\n\tif socketHost.Socket == \"\" && hasDockerHost {\n\t\t// Cases: 4A\n\t\tlog.Debugf(\"Defaulting container socket to DOCKER_HOST\")\n\t\tsocketHost.Socket = socketHost.Host\n\t}\n\t// Set sane default socket location if user omitted it\n\tif socketHost.Socket == \"\" {\n\t\t// Cases: 4B\n\t\tsocket, _ := socketLocation()\n\t\t// socket is empty if it isn't found, so assignment here is at worst a no-op\n\t\tlog.Debugf(\"Defaulting container socket to default '%s'\", socket)\n\t\tsocketHost.Socket = socket\n\t}\n\n\t// Exit if both the DOCKER_HOST and socket are fulfilled\n\tif hasDockerHost {\n\t\t// Cases: 1A, 2A, 3A, 4A\n\t\tif !isDockerHostURI(socketHost.Socket) {\n\t\t\t// Cases: 1A, 2A\n\t\t\tlog.Debugf(\"DOCKER_HOST is set, but socket is invalid '%s'\", socketHost.Socket)\n\t\t}\n\t\treturn socketHost, nil\n\t}\n\n\t// Set a sane DOCKER_HOST default if we can\n\tif isDockerHostURI(socketHost.Socket) {\n\t\t// Cases: 3B\n\t\tlog.Debugf(\"Setting DOCKER_HOST to container socket '%s'\", socketHost.Socket)\n\t\tsocketHost.Host = socketHost.Socket\n\t\t// Both DOCKER_HOST and container socket are valid; short-circuit exit\n\t\treturn socketHost, nil\n\t}\n\n\t// Here there is no DOCKER_HOST _and_ the supplied container socket is not a valid URI (either invalid or a file path)\n\t// Cases: 2B <- but is already handled at the top\n\t// I.e. this path should never be taken\n\treturn SocketAndHost{}, fmt.Errorf(\"no DOCKER_HOST and an invalid container socket '%s'\", socketHost.Socket)\n}\n"
  },
  {
    "path": "pkg/container/docker_socket_test.go",
    "content": "package container\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\tassert \"github.com/stretchr/testify/assert\"\n)\n\nfunc init() {\n\tlog.SetLevel(log.DebugLevel)\n}\n\nvar originalCommonSocketLocations = CommonSocketLocations\n\nfunc TestGetSocketAndHostWithSocket(t *testing.T) {\n\t// Arrange\n\tCommonSocketLocations = originalCommonSocketLocations\n\tdockerHost := \"unix:///my/docker/host.sock\"\n\tsocketURI := \"/path/to/my.socket\"\n\tos.Setenv(\"DOCKER_HOST\", dockerHost)\n\n\t// Act\n\tret, err := GetSocketAndHost(socketURI)\n\n\t// Assert\n\tassert.Nil(t, err)\n\tassert.Equal(t, SocketAndHost{socketURI, dockerHost}, ret)\n}\n\nfunc TestGetSocketAndHostNoSocket(t *testing.T) {\n\t// Arrange\n\tdockerHost := \"unix:///my/docker/host.sock\"\n\tos.Setenv(\"DOCKER_HOST\", dockerHost)\n\n\t// Act\n\tret, err := GetSocketAndHost(\"\")\n\n\t// Assert\n\tassert.Nil(t, err)\n\tassert.Equal(t, SocketAndHost{dockerHost, dockerHost}, ret)\n}\n\nfunc TestGetSocketAndHostOnlySocket(t *testing.T) {\n\t// Arrange\n\tsocketURI := \"/path/to/my.socket\"\n\tos.Unsetenv(\"DOCKER_HOST\")\n\tCommonSocketLocations = originalCommonSocketLocations\n\tdefaultSocket, defaultSocketFound := socketLocation()\n\n\t// Act\n\tret, err := GetSocketAndHost(socketURI)\n\n\t// Assert\n\tassert.NoError(t, err, \"Expected no error from GetSocketAndHost\")\n\tassert.Equal(t, true, defaultSocketFound, \"Expected to find default socket\")\n\tassert.Equal(t, socketURI, ret.Socket, \"Expected socket to match common location\")\n\tassert.Equal(t, defaultSocket, ret.Host, \"Expected ret.Host to match default socket location\")\n}\n\nfunc TestGetSocketAndHostDontMount(t *testing.T) {\n\t// Arrange\n\tCommonSocketLocations = originalCommonSocketLocations\n\tdockerHost := \"unix:///my/docker/host.sock\"\n\tos.Setenv(\"DOCKER_HOST\", dockerHost)\n\n\t// Act\n\tret, err := GetSocketAndHost(\"-\")\n\n\t// Assert\n\tassert.Nil(t, err)\n\tassert.Equal(t, SocketAndHost{\"-\", dockerHost}, ret)\n}\n\nfunc TestGetSocketAndHostNoHostNoSocket(t *testing.T) {\n\t// Arrange\n\tCommonSocketLocations = originalCommonSocketLocations\n\tos.Unsetenv(\"DOCKER_HOST\")\n\tdefaultSocket, found := socketLocation()\n\n\t// Act\n\tret, err := GetSocketAndHost(\"\")\n\n\t// Assert\n\tassert.Equal(t, true, found, \"Expected a default socket to be found\")\n\tassert.Nil(t, err, \"Expected no error from GetSocketAndHost\")\n\tassert.Equal(t, SocketAndHost{defaultSocket, defaultSocket}, ret, \"Expected to match default socket location\")\n}\n\n// Catch\n// > Your code breaks setting DOCKER_HOST if shouldMount is false.\n// > This happens if neither DOCKER_HOST nor --container-daemon-socket has a value, but socketLocation() returns a URI\nfunc TestGetSocketAndHostNoHostNoSocketDefaultLocation(t *testing.T) {\n\t// Arrange\n\tmySocketFile, tmpErr := os.CreateTemp(\"\", \"act-*.sock\")\n\tmySocket := mySocketFile.Name()\n\tunixSocket := \"unix://\" + mySocket\n\tdefer os.RemoveAll(mySocket)\n\tassert.NoError(t, tmpErr)\n\tos.Unsetenv(\"DOCKER_HOST\")\n\n\tCommonSocketLocations = []string{mySocket}\n\tdefaultSocket, found := socketLocation()\n\n\t// Act\n\tret, err := GetSocketAndHost(\"\")\n\n\t// Assert\n\tassert.Equal(t, unixSocket, defaultSocket, \"Expected default socket to match common socket location\")\n\tassert.Equal(t, true, found, \"Expected default socket to be found\")\n\tassert.Nil(t, err, \"Expected no error from GetSocketAndHost\")\n\tassert.Equal(t, SocketAndHost{unixSocket, unixSocket}, ret, \"Expected to match default socket location\")\n}\n\nfunc TestGetSocketAndHostNoHostInvalidSocket(t *testing.T) {\n\t// Arrange\n\tos.Unsetenv(\"DOCKER_HOST\")\n\tmySocket := \"/my/socket/path.sock\"\n\tCommonSocketLocations = []string{\"/unusual\", \"/socket\", \"/location\"}\n\tdefaultSocket, found := socketLocation()\n\n\t// Act\n\tret, err := GetSocketAndHost(mySocket)\n\n\t// Assert\n\tassert.Equal(t, false, found, \"Expected no default socket to be found\")\n\tassert.Equal(t, \"\", defaultSocket, \"Expected no default socket to be found\")\n\tassert.Equal(t, SocketAndHost{}, ret, \"Expected to match default socket location\")\n\tassert.Error(t, err, \"Expected an error in invalid state\")\n}\n\nfunc TestGetSocketAndHostOnlySocketValidButUnusualLocation(t *testing.T) {\n\t// Arrange\n\tsocketURI := \"unix:///path/to/my.socket\"\n\tCommonSocketLocations = []string{\"/unusual\", \"/location\"}\n\tos.Unsetenv(\"DOCKER_HOST\")\n\tdefaultSocket, found := socketLocation()\n\n\t// Act\n\tret, err := GetSocketAndHost(socketURI)\n\n\t// Assert\n\t// Default socket locations\n\tassert.Equal(t, \"\", defaultSocket, \"Expect default socket location to be empty\")\n\tassert.Equal(t, false, found, \"Expected no default socket to be found\")\n\t// Sane default\n\tassert.Nil(t, err, \"Expect no error from GetSocketAndHost\")\n\tassert.Equal(t, socketURI, ret.Host, \"Expect host to default to unusual socket\")\n}\n"
  },
  {
    "path": "pkg/container/docker_stub.go",
    "content": "//go:build WITHOUT_DOCKER || !(linux || darwin || windows || netbsd)\n\npackage container\n\nimport (\n\t\"context\"\n\t\"runtime\"\n\n\t\"github.com/docker/docker/api/types/system\"\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/pkg/errors\"\n)\n\n// ImageExistsLocally returns a boolean indicating if an image with the\n// requested name, tag and architecture exists in the local docker image store\nfunc ImageExistsLocally(ctx context.Context, imageName string, platform string) (bool, error) {\n\treturn false, errors.New(\"Unsupported Operation\")\n}\n\n// RemoveImage removes image from local store, the function is used to run different\n// container image architectures\nfunc RemoveImage(ctx context.Context, imageName string, force bool, pruneChildren bool) (bool, error) {\n\treturn false, errors.New(\"Unsupported Operation\")\n}\n\n// NewDockerBuildExecutor function to create a run executor for the container\nfunc NewDockerBuildExecutor(input NewDockerBuildExecutorInput) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\treturn errors.New(\"Unsupported Operation\")\n\t}\n}\n\n// NewDockerPullExecutor function to create a run executor for the container\nfunc NewDockerPullExecutor(input NewDockerPullExecutorInput) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\treturn errors.New(\"Unsupported Operation\")\n\t}\n}\n\n// NewContainer creates a reference to a container\nfunc NewContainer(input *NewContainerInput) ExecutionsEnvironment {\n\treturn nil\n}\n\nfunc RunnerArch(ctx context.Context) string {\n\treturn runtime.GOOS\n}\n\nfunc GetHostInfo(ctx context.Context) (info system.Info, err error) {\n\treturn system.Info{}, nil\n}\n\nfunc NewDockerVolumeRemoveExecutor(volume string, force bool) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc NewDockerNetworkCreateExecutor(name string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc NewDockerNetworkRemoveExecutor(name string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "pkg/container/docker_volume.go",
    "content": "//go:build !(WITHOUT_DOCKER || !(linux || darwin || windows || netbsd))\n\npackage container\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/volume\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\nfunc NewDockerVolumeRemoveExecutor(volumeName string, force bool) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tcli, err := GetDockerClient(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer cli.Close()\n\n\t\tlist, err := cli.VolumeList(ctx, volume.ListOptions{Filters: filters.NewArgs()})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfor _, vol := range list.Volumes {\n\t\t\tif vol.Name == volumeName {\n\t\t\t\treturn removeExecutor(volumeName, force)(ctx)\n\t\t\t}\n\t\t}\n\n\t\t// Volume not found - do nothing\n\t\treturn nil\n\t}\n}\n\nfunc removeExecutor(volume string, force bool) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tlogger.Debugf(\"%sdocker volume rm %s\", logPrefix, volume)\n\n\t\tif common.Dryrun(ctx) {\n\t\t\treturn nil\n\t\t}\n\n\t\tcli, err := GetDockerClient(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer cli.Close()\n\n\t\treturn cli.VolumeRemove(ctx, volume, force)\n\t}\n}\n"
  },
  {
    "path": "pkg/container/executions_environment.go",
    "content": "package container\n\nimport \"context\"\n\ntype ExecutionsEnvironment interface {\n\tContainer\n\tToContainerPath(string) string\n\tGetActPath() string\n\tGetPathVariableName() string\n\tDefaultPathVariable() string\n\tJoinPathVariable(...string) string\n\tGetRunnerContext(ctx context.Context) map[string]interface{}\n\t// On windows PATH and Path are the same key\n\tIsEnvironmentCaseInsensitive() bool\n}\n"
  },
  {
    "path": "pkg/container/host_environment.go",
    "content": "package container\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/go-git/go-billy/v5/helper/polyfill\"\n\t\"github.com/go-git/go-billy/v5/osfs\"\n\t\"github.com/go-git/go-git/v5/plumbing/format/gitignore\"\n\t\"golang.org/x/term\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/filecollector\"\n\t\"github.com/nektos/act/pkg/lookpath\"\n)\n\ntype HostEnvironment struct {\n\tPath      string\n\tTmpDir    string\n\tToolCache string\n\tWorkdir   string\n\tActPath   string\n\tCleanUp   func()\n\tStdOut    io.Writer\n}\n\nfunc (e *HostEnvironment) Create(_ []string, _ []string) common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc (e *HostEnvironment) Close() common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc (e *HostEnvironment) Copy(destPath string, files ...*FileEntry) common.Executor {\n\treturn func(_ context.Context) error {\n\t\tfor _, f := range files {\n\t\t\tif err := os.MkdirAll(filepath.Dir(filepath.Join(destPath, f.Name)), 0o777); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := os.WriteFile(filepath.Join(destPath, f.Name), []byte(f.Body), fs.FileMode(f.Mode)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (e *HostEnvironment) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error {\n\tif err := os.RemoveAll(destPath); err != nil {\n\t\treturn err\n\t}\n\ttr := tar.NewReader(tarStream)\n\tcp := &filecollector.CopyCollector{\n\t\tDstDir: destPath,\n\t}\n\tfor {\n\t\tti, err := tr.Next()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\treturn nil\n\t\t} else if err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif ti.FileInfo().IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\tif ctx.Err() != nil {\n\t\t\treturn fmt.Errorf(\"CopyTarStream has been cancelled\")\n\t\t}\n\t\tif err := cp.WriteFile(ti.Name, ti.FileInfo(), ti.Linkname, tr); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n}\n\nfunc (e *HostEnvironment) CopyDir(destPath string, srcPath string, useGitIgnore bool) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tsrcPrefix := filepath.Dir(srcPath)\n\t\tif !strings.HasSuffix(srcPrefix, string(filepath.Separator)) {\n\t\t\tsrcPrefix += string(filepath.Separator)\n\t\t}\n\t\tlogger.Debugf(\"Stripping prefix:%s src:%s\", srcPrefix, srcPath)\n\t\tvar ignorer gitignore.Matcher\n\t\tif useGitIgnore {\n\t\t\tps, err := gitignore.ReadPatterns(polyfill.New(osfs.New(srcPath)), nil)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Debugf(\"Error loading .gitignore: %v\", err)\n\t\t\t}\n\n\t\t\tignorer = gitignore.NewMatcher(ps)\n\t\t}\n\t\tfc := &filecollector.FileCollector{\n\t\t\tFs:        &filecollector.DefaultFs{},\n\t\t\tIgnorer:   ignorer,\n\t\t\tSrcPath:   srcPath,\n\t\t\tSrcPrefix: srcPrefix,\n\t\t\tHandler: &filecollector.CopyCollector{\n\t\t\t\tDstDir: destPath,\n\t\t\t},\n\t\t}\n\t\treturn filepath.Walk(srcPath, fc.CollectFiles(ctx, []string{}))\n\t}\n}\n\nfunc (e *HostEnvironment) GetContainerArchive(ctx context.Context, srcPath string) (io.ReadCloser, error) {\n\tbuf := &bytes.Buffer{}\n\ttw := tar.NewWriter(buf)\n\tdefer tw.Close()\n\tsrcPath = filepath.Clean(srcPath)\n\tfi, err := os.Lstat(srcPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttc := &filecollector.TarCollector{\n\t\tTarWriter: tw,\n\t}\n\tif fi.IsDir() {\n\t\tsrcPrefix := srcPath\n\t\tif !strings.HasSuffix(srcPrefix, string(filepath.Separator)) {\n\t\t\tsrcPrefix += string(filepath.Separator)\n\t\t}\n\t\tfc := &filecollector.FileCollector{\n\t\t\tFs:        &filecollector.DefaultFs{},\n\t\t\tSrcPath:   srcPath,\n\t\t\tSrcPrefix: srcPrefix,\n\t\t\tHandler:   tc,\n\t\t}\n\t\terr = filepath.Walk(srcPath, fc.CollectFiles(ctx, []string{}))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tvar f io.ReadCloser\n\t\tvar linkname string\n\t\tif fi.Mode()&fs.ModeSymlink != 0 {\n\t\t\tlinkname, err = os.Readlink(srcPath)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\tf, err = os.Open(srcPath)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdefer f.Close()\n\t\t}\n\t\terr := tc.WriteFile(fi.Name(), fi, linkname, f)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn io.NopCloser(buf), nil\n}\n\nfunc (e *HostEnvironment) Pull(_ bool) common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc (e *HostEnvironment) Start(_ bool) common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\ntype ptyWriter struct {\n\tOut       io.Writer\n\tAutoStop  bool\n\tdirtyLine bool\n}\n\nfunc (w *ptyWriter) Write(buf []byte) (int, error) {\n\tif w.AutoStop && len(buf) > 0 && buf[len(buf)-1] == 4 {\n\t\tn, err := w.Out.Write(buf[:len(buf)-1])\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tif w.dirtyLine || len(buf) > 1 && buf[len(buf)-2] != '\\n' {\n\t\t\t_, _ = w.Out.Write([]byte(\"\\n\"))\n\t\t\treturn n, io.EOF\n\t\t}\n\t\treturn n, io.EOF\n\t}\n\tw.dirtyLine = strings.LastIndex(string(buf), \"\\n\") < len(buf)-1\n\treturn w.Out.Write(buf)\n}\n\ntype localEnv struct {\n\tenv map[string]string\n}\n\nfunc (l *localEnv) Getenv(name string) string {\n\tif runtime.GOOS == \"windows\" {\n\t\tfor k, v := range l.env {\n\t\t\tif strings.EqualFold(name, k) {\n\t\t\t\treturn v\n\t\t\t}\n\t\t}\n\t\treturn \"\"\n\t}\n\treturn l.env[name]\n}\n\nfunc lookupPathHost(cmd string, env map[string]string, writer io.Writer) (string, error) {\n\tf, err := lookpath.LookPath2(cmd, &localEnv{env: env})\n\tif err != nil {\n\t\terr := \"Cannot find: \" + fmt.Sprint(cmd) + \" in PATH\"\n\t\tif _, _err := writer.Write([]byte(err + \"\\n\")); _err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"%v: %w\", err, _err)\n\t\t}\n\t\treturn \"\", errors.New(err)\n\t}\n\treturn f, nil\n}\n\nfunc setupPty(cmd *exec.Cmd, cmdline string) (*os.File, *os.File, error) {\n\tppty, tty, err := openPty()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif term.IsTerminal(int(tty.Fd())) {\n\t\t_, err := term.MakeRaw(int(tty.Fd()))\n\t\tif err != nil {\n\t\t\tppty.Close()\n\t\t\ttty.Close()\n\t\t\treturn nil, nil, err\n\t\t}\n\t}\n\tcmd.Stdin = tty\n\tcmd.Stdout = tty\n\tcmd.Stderr = tty\n\tcmd.SysProcAttr = getSysProcAttr(cmdline, true)\n\treturn ppty, tty, nil\n}\n\nfunc writeKeepAlive(ppty io.Writer) {\n\tc := 1\n\tvar err error\n\tfor c == 1 && err == nil {\n\t\tc, err = ppty.Write([]byte{4})\n\t\t<-time.After(time.Second)\n\t}\n}\n\nfunc copyPtyOutput(writer io.Writer, ppty io.Reader, finishLog context.CancelFunc) {\n\tdefer func() {\n\t\tfinishLog()\n\t}()\n\tif _, err := io.Copy(writer, ppty); err != nil {\n\t\treturn\n\t}\n}\n\nfunc (e *HostEnvironment) UpdateFromImageEnv(_ *map[string]string) common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc getEnvListFromMap(env map[string]string) []string {\n\tenvList := make([]string, 0)\n\tfor k, v := range env {\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", k, v))\n\t}\n\treturn envList\n}\n\nfunc (e *HostEnvironment) exec(ctx context.Context, command []string, cmdline string, env map[string]string, _, workdir string) error {\n\tenvList := getEnvListFromMap(env)\n\tvar wd string\n\tif workdir != \"\" {\n\t\tif filepath.IsAbs(workdir) {\n\t\t\twd = workdir\n\t\t} else {\n\t\t\twd = filepath.Join(e.Path, workdir)\n\t\t}\n\t} else {\n\t\twd = e.Path\n\t}\n\tf, err := lookupPathHost(command[0], env, e.StdOut)\n\tif err != nil {\n\t\treturn err\n\t}\n\tcmd := exec.CommandContext(ctx, f)\n\tcmd.Path = f\n\tcmd.Args = command\n\tcmd.Stdin = nil\n\tcmd.Stdout = e.StdOut\n\tcmd.Env = envList\n\tcmd.Stderr = e.StdOut\n\tcmd.Dir = wd\n\tcmd.SysProcAttr = getSysProcAttr(cmdline, false)\n\tvar ppty *os.File\n\tvar tty *os.File\n\tdefer func() {\n\t\tif ppty != nil {\n\t\t\tppty.Close()\n\t\t}\n\t\tif tty != nil {\n\t\t\ttty.Close()\n\t\t}\n\t}()\n\tif true /* allocate Terminal */ {\n\t\tvar err error\n\t\tppty, tty, err = setupPty(cmd, cmdline)\n\t\tif err != nil {\n\t\t\tcommon.Logger(ctx).Debugf(\"Failed to setup Pty %v\\n\", err.Error())\n\t\t}\n\t}\n\twriter := &ptyWriter{Out: e.StdOut}\n\tlogctx, finishLog := context.WithCancel(context.Background())\n\tif ppty != nil {\n\t\tgo copyPtyOutput(writer, ppty, finishLog)\n\t} else {\n\t\tfinishLog()\n\t}\n\tif ppty != nil {\n\t\tgo writeKeepAlive(ppty)\n\t}\n\terr = cmd.Run()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif tty != nil {\n\t\twriter.AutoStop = true\n\t\tif _, err := tty.Write([]byte(\"\\x04\")); err != nil {\n\t\t\tcommon.Logger(ctx).Debug(\"Failed to write EOT\")\n\t\t}\n\t}\n\t<-logctx.Done()\n\n\tif ppty != nil {\n\t\tppty.Close()\n\t\tppty = nil\n\t}\n\treturn err\n}\n\nfunc (e *HostEnvironment) Exec(command []string /*cmdline string, */, env map[string]string, user, workdir string) common.Executor {\n\treturn e.ExecWithCmdLine(command, \"\", env, user, workdir)\n}\n\nfunc (e *HostEnvironment) ExecWithCmdLine(command []string, cmdline string, env map[string]string, user, workdir string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tif err := e.exec(ctx, command, cmdline, env, user, workdir); err != nil {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn fmt.Errorf(\"this step has been cancelled: %w\", err)\n\t\t\tdefault:\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (e *HostEnvironment) UpdateFromEnv(srcPath string, env *map[string]string) common.Executor {\n\treturn parseEnvFile(e, srcPath, env)\n}\n\nfunc (e *HostEnvironment) Remove() common.Executor {\n\treturn func(_ context.Context) error {\n\t\tif e.CleanUp != nil {\n\t\t\te.CleanUp()\n\t\t}\n\t\treturn os.RemoveAll(e.Path)\n\t}\n}\n\nfunc (e *HostEnvironment) ToContainerPath(path string) string {\n\tif bp, err := filepath.Rel(e.Workdir, path); err != nil {\n\t\treturn filepath.Join(e.Path, bp)\n\t} else if filepath.Clean(e.Workdir) == filepath.Clean(path) {\n\t\treturn e.Path\n\t}\n\treturn path\n}\n\nfunc (e *HostEnvironment) GetActPath() string {\n\tactPath := e.ActPath\n\tif runtime.GOOS == \"windows\" {\n\t\tactPath = strings.ReplaceAll(actPath, \"\\\\\", \"/\")\n\t}\n\treturn actPath\n}\n\nfunc (*HostEnvironment) GetPathVariableName() string {\n\tif runtime.GOOS == \"plan9\" {\n\t\treturn \"path\"\n\t} else if runtime.GOOS == \"windows\" {\n\t\treturn \"Path\" // Actually we need a case insensitive map\n\t}\n\treturn \"PATH\"\n}\n\nfunc (e *HostEnvironment) DefaultPathVariable() string {\n\tv, _ := os.LookupEnv(e.GetPathVariableName())\n\treturn v\n}\n\nfunc (*HostEnvironment) JoinPathVariable(paths ...string) string {\n\treturn strings.Join(paths, string(filepath.ListSeparator))\n}\n\n// Reference for Arch values for runner.arch\n// https://docs.github.com/en/actions/learn-github-actions/contexts#runner-context\nfunc goArchToActionArch(arch string) string {\n\tarchMapper := map[string]string{\n\t\t\"amd64\":   \"X64\",\n\t\t\"x86_64\":  \"X64\",\n\t\t\"386\":     \"X86\",\n\t\t\"aarch64\": \"ARM64\",\n\t}\n\tif arch, ok := archMapper[arch]; ok {\n\t\treturn arch\n\t}\n\treturn arch\n}\n\nfunc goOsToActionOs(os string) string {\n\tosMapper := map[string]string{\n\t\t\"linux\":   \"Linux\",\n\t\t\"windows\": \"Windows\",\n\t\t\"darwin\":  \"macOS\",\n\t}\n\tif os, ok := osMapper[os]; ok {\n\t\treturn os\n\t}\n\treturn os\n}\n\nfunc (e *HostEnvironment) GetRunnerContext(_ context.Context) map[string]interface{} {\n\treturn map[string]interface{}{\n\t\t\"os\":         goOsToActionOs(runtime.GOOS),\n\t\t\"arch\":       goArchToActionArch(runtime.GOARCH),\n\t\t\"temp\":       e.TmpDir,\n\t\t\"tool_cache\": e.ToolCache,\n\t}\n}\n\nfunc (e *HostEnvironment) GetHealth(_ context.Context) Health {\n\treturn HealthHealthy\n}\n\nfunc (e *HostEnvironment) ReplaceLogWriter(stdout io.Writer, _ io.Writer) (io.Writer, io.Writer) {\n\torg := e.StdOut\n\te.StdOut = stdout\n\treturn org, org\n}\n\nfunc (*HostEnvironment) IsEnvironmentCaseInsensitive() bool {\n\treturn runtime.GOOS == \"windows\"\n}\n"
  },
  {
    "path": "pkg/container/host_environment_test.go",
    "content": "package container\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\n// Type assert HostEnvironment implements ExecutionsEnvironment\nvar _ ExecutionsEnvironment = &HostEnvironment{}\n\nfunc TestCopyDir(t *testing.T) {\n\tdir, err := os.MkdirTemp(\"\", \"test-host-env-*\")\n\tassert.NoError(t, err)\n\tdefer os.RemoveAll(dir)\n\tctx := context.Background()\n\te := &HostEnvironment{\n\t\tPath:      filepath.Join(dir, \"path\"),\n\t\tTmpDir:    filepath.Join(dir, \"tmp\"),\n\t\tToolCache: filepath.Join(dir, \"tool_cache\"),\n\t\tActPath:   filepath.Join(dir, \"act_path\"),\n\t\tStdOut:    os.Stdout,\n\t\tWorkdir:   path.Join(\"testdata\", \"scratch\"),\n\t}\n\t_ = os.MkdirAll(e.Path, 0700)\n\t_ = os.MkdirAll(e.TmpDir, 0700)\n\t_ = os.MkdirAll(e.ToolCache, 0700)\n\t_ = os.MkdirAll(e.ActPath, 0700)\n\terr = e.CopyDir(e.Workdir, e.Path, true)(ctx)\n\tassert.NoError(t, err)\n}\n\nfunc TestGetContainerArchive(t *testing.T) {\n\tdir, err := os.MkdirTemp(\"\", \"test-host-env-*\")\n\tassert.NoError(t, err)\n\tdefer os.RemoveAll(dir)\n\tctx := context.Background()\n\te := &HostEnvironment{\n\t\tPath:      filepath.Join(dir, \"path\"),\n\t\tTmpDir:    filepath.Join(dir, \"tmp\"),\n\t\tToolCache: filepath.Join(dir, \"tool_cache\"),\n\t\tActPath:   filepath.Join(dir, \"act_path\"),\n\t\tStdOut:    os.Stdout,\n\t\tWorkdir:   path.Join(\"testdata\", \"scratch\"),\n\t}\n\t_ = os.MkdirAll(e.Path, 0700)\n\t_ = os.MkdirAll(e.TmpDir, 0700)\n\t_ = os.MkdirAll(e.ToolCache, 0700)\n\t_ = os.MkdirAll(e.ActPath, 0700)\n\texpectedContent := []byte(\"sdde/7sh\")\n\terr = os.WriteFile(filepath.Join(e.Path, \"action.yml\"), expectedContent, 0600)\n\tassert.NoError(t, err)\n\tarchive, err := e.GetContainerArchive(ctx, e.Path)\n\tassert.NoError(t, err)\n\tdefer archive.Close()\n\treader := tar.NewReader(archive)\n\th, err := reader.Next()\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"action.yml\", h.Name)\n\tcontent, err := io.ReadAll(reader)\n\tassert.NoError(t, err)\n\tassert.Equal(t, expectedContent, content)\n\t_, err = reader.Next()\n\tassert.ErrorIs(t, err, io.EOF)\n}\n"
  },
  {
    "path": "pkg/container/linux_container_environment_extensions.go",
    "content": "package container\n\nimport (\n\t\"context\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype LinuxContainerEnvironmentExtensions struct {\n}\n\n// Resolves the equivalent host path inside the container\n// This is required for windows and WSL 2 to translate things like C:\\Users\\Myproject to /mnt/users/Myproject\n// For use in docker volumes and binds\nfunc (*LinuxContainerEnvironmentExtensions) ToContainerPath(path string) string {\n\tif runtime.GOOS == \"windows\" && strings.Contains(path, \"/\") {\n\t\tlog.Error(\"You cannot specify linux style local paths (/mnt/etc) on Windows as it does not understand them.\")\n\t\treturn \"\"\n\t}\n\n\tabspath, err := filepath.Abs(path)\n\tif err != nil {\n\t\tlog.Error(err)\n\t\treturn \"\"\n\t}\n\n\t// Test if the path is a windows path\n\twindowsPathRegex := regexp.MustCompile(`^([a-zA-Z]):\\\\(.+)$`)\n\twindowsPathComponents := windowsPathRegex.FindStringSubmatch(abspath)\n\n\t// Return as-is if no match\n\tif windowsPathComponents == nil {\n\t\treturn abspath\n\t}\n\n\t// Convert to WSL2-compatible path if it is a windows path\n\t// NOTE: Cannot use filepath because it will use the wrong path separators assuming we want the path to be windows\n\t// based if running on Windows, and because we are feeding this to Docker, GoLang auto-path-translate doesn't work.\n\tdriveLetter := strings.ToLower(windowsPathComponents[1])\n\ttranslatedPath := strings.ReplaceAll(windowsPathComponents[2], `\\`, `/`)\n\t// Should make something like /mnt/c/Users/person/My Folder/MyActProject\n\tresult := strings.Join([]string{\"/mnt\", driveLetter, translatedPath}, `/`)\n\treturn result\n}\n\nfunc (*LinuxContainerEnvironmentExtensions) GetActPath() string {\n\treturn \"/var/run/act\"\n}\n\nfunc (*LinuxContainerEnvironmentExtensions) GetPathVariableName() string {\n\treturn \"PATH\"\n}\n\nfunc (*LinuxContainerEnvironmentExtensions) DefaultPathVariable() string {\n\treturn \"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"\n}\n\nfunc (*LinuxContainerEnvironmentExtensions) JoinPathVariable(paths ...string) string {\n\treturn strings.Join(paths, \":\")\n}\n\nfunc (*LinuxContainerEnvironmentExtensions) GetRunnerContext(ctx context.Context) map[string]interface{} {\n\treturn map[string]interface{}{\n\t\t\"os\":         \"Linux\",\n\t\t\"arch\":       RunnerArch(ctx),\n\t\t\"temp\":       \"/tmp\",\n\t\t\"tool_cache\": \"/opt/hostedtoolcache\",\n\t}\n}\n\nfunc (*LinuxContainerEnvironmentExtensions) IsEnvironmentCaseInsensitive() bool {\n\treturn false\n}\n"
  },
  {
    "path": "pkg/container/linux_container_environment_extensions_test.go",
    "content": "package container\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestContainerPath(t *testing.T) {\n\ttype containerPathJob struct {\n\t\tdestinationPath string\n\t\tsourcePath      string\n\t\tworkDir         string\n\t}\n\n\tlinuxcontainerext := &LinuxContainerEnvironmentExtensions{}\n\n\tif runtime.GOOS == \"windows\" {\n\t\tcwd, err := os.Getwd()\n\t\tif err != nil {\n\t\t\tlog.Error(err)\n\t\t}\n\n\t\trootDrive := os.Getenv(\"SystemDrive\")\n\t\trootDriveLetter := strings.ReplaceAll(strings.ToLower(rootDrive), `:`, \"\")\n\t\tfor _, v := range []containerPathJob{\n\t\t\t{\"/mnt/c/Users/act/go/src/github.com/nektos/act\", \"C:\\\\Users\\\\act\\\\go\\\\src\\\\github.com\\\\nektos\\\\act\\\\\", \"\"},\n\t\t\t{\"/mnt/f/work/dir\", `F:\\work\\dir`, \"\"},\n\t\t\t{\"/mnt/c/windows/to/unix\", \"windows\\\\to\\\\unix\", fmt.Sprintf(\"%s\\\\\", rootDrive)},\n\t\t\t{fmt.Sprintf(\"/mnt/%v/act\", rootDriveLetter), \"act\", fmt.Sprintf(\"%s\\\\\", rootDrive)},\n\t\t} {\n\t\t\tif v.workDir != \"\" {\n\t\t\t\tif err := os.Chdir(v.workDir); err != nil {\n\t\t\t\t\tlog.Error(err)\n\t\t\t\t\tt.Fail()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassert.Equal(t, v.destinationPath, linuxcontainerext.ToContainerPath(v.sourcePath))\n\t\t}\n\n\t\tif err := os.Chdir(cwd); err != nil {\n\t\t\tlog.Error(err)\n\t\t}\n\t} else {\n\t\tcwd, err := os.Getwd()\n\t\tif err != nil {\n\t\t\tlog.Error(err)\n\t\t}\n\t\tfor _, v := range []containerPathJob{\n\t\t\t{\"/home/act/go/src/github.com/nektos/act\", \"/home/act/go/src/github.com/nektos/act\", \"\"},\n\t\t\t{\"/home/act\", `/home/act/`, \"\"},\n\t\t\t{cwd, \".\", \"\"},\n\t\t} {\n\t\t\tassert.Equal(t, v.destinationPath, linuxcontainerext.ToContainerPath(v.sourcePath))\n\t\t}\n\t}\n}\n\ntype typeAssertMockContainer struct {\n\tContainer\n\tLinuxContainerEnvironmentExtensions\n}\n\n// Type assert Container + LinuxContainerEnvironmentExtensions implements ExecutionsEnvironment\nvar _ ExecutionsEnvironment = &typeAssertMockContainer{}\n"
  },
  {
    "path": "pkg/container/parse_env_file.go",
    "content": "package container\n\nimport (\n\t\"archive/tar\"\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n)\n\nfunc parseEnvFile(e Container, srcPath string, env *map[string]string) common.Executor {\n\tlocalEnv := *env\n\treturn func(ctx context.Context) error {\n\t\tenvTar, err := e.GetContainerArchive(ctx, srcPath)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tdefer envTar.Close()\n\t\treader := tar.NewReader(envTar)\n\t\t_, err = reader.Next()\n\t\tif err != nil && err != io.EOF {\n\t\t\treturn err\n\t\t}\n\t\ts := bufio.NewScanner(reader)\n\t\ts.Buffer(nil, 1024*1024*1024) // increase buffer to 1GB to avoid scanner buffer overflow\n\t\tfirstLine := true\n\t\tfor s.Scan() {\n\t\t\tline := s.Text()\n\t\t\tif firstLine {\n\t\t\t\tfirstLine = false\n\t\t\t\t// skip utf8 bom, powershell 5 legacy uses it for utf8\n\t\t\t\tif len(line) >= 3 && line[0] == 239 && line[1] == 187 && line[2] == 191 {\n\t\t\t\t\tline = line[3:]\n\t\t\t\t}\n\t\t\t}\n\t\t\tsingleLineEnv := strings.Index(line, \"=\")\n\t\t\tmultiLineEnv := strings.Index(line, \"<<\")\n\t\t\tif singleLineEnv != -1 && (multiLineEnv == -1 || singleLineEnv < multiLineEnv) {\n\t\t\t\tlocalEnv[line[:singleLineEnv]] = line[singleLineEnv+1:]\n\t\t\t} else if multiLineEnv != -1 {\n\t\t\t\tmultiLineEnvContent := \"\"\n\t\t\t\tmultiLineEnvDelimiter := line[multiLineEnv+2:]\n\t\t\t\tdelimiterFound := false\n\t\t\t\tfor s.Scan() {\n\t\t\t\t\tcontent := s.Text()\n\t\t\t\t\tif content == multiLineEnvDelimiter {\n\t\t\t\t\t\tdelimiterFound = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif multiLineEnvContent != \"\" {\n\t\t\t\t\t\tmultiLineEnvContent += \"\\n\"\n\t\t\t\t\t}\n\t\t\t\t\tmultiLineEnvContent += content\n\t\t\t\t}\n\t\t\t\tif !delimiterFound {\n\t\t\t\t\treturn fmt.Errorf(\"invalid format delimiter '%v' not found before end of file\", multiLineEnvDelimiter)\n\t\t\t\t}\n\t\t\t\tlocalEnv[line[:multiLineEnv]] = multiLineEnvContent\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"invalid format '%v', expected a line with '=' or '<<'\", line)\n\t\t\t}\n\t\t}\n\t\tenv = &localEnv\n\t\treturn s.Err()\n\t}\n}\n"
  },
  {
    "path": "pkg/container/testdata/Dockerfile",
    "content": "FROM scratch\nENV PATH=\"/this/path/does/not/exists/anywhere:/this/either\"\nENV SOME_RANDOM_VAR=\"\"\nENV ANOTHER_ONE=\"BUT_I_HAVE_VALUE\"\nENV CONFLICT_VAR=\"I_EXIST_ONLY_HERE\"\n"
  },
  {
    "path": "pkg/container/testdata/docker-pull-options/config.json",
    "content": "{\n  \"auths\": {\n          \"https://index.docker.io/v1/\": {\n                  \"auth\": \"dXNlcm5hbWU6cGFzc3dvcmQK\"\n          }\n  }\n}\n"
  },
  {
    "path": "pkg/container/testdata/scratch/test.txt",
    "content": "testfile"
  },
  {
    "path": "pkg/container/testdata/utf8.env",
    "content": "﻿FOO=BAR\nHELLO=您好\nBAR=FOO"
  },
  {
    "path": "pkg/container/testdata/valid.env",
    "content": "ENV1=value1\n"
  },
  {
    "path": "pkg/container/testdata/valid.label",
    "content": "LABEL1=value1\n"
  },
  {
    "path": "pkg/container/util.go",
    "content": "//go:build (!windows && !plan9 && !openbsd) || (!windows && !plan9 && !mips64)\n\npackage container\n\nimport (\n\t\"os\"\n\t\"syscall\"\n\n\t\"github.com/creack/pty\"\n)\n\nfunc getSysProcAttr(_ string, tty bool) *syscall.SysProcAttr {\n\tif tty {\n\t\treturn &syscall.SysProcAttr{\n\t\t\tSetsid:  true,\n\t\t\tSetctty: true,\n\t\t}\n\t}\n\treturn &syscall.SysProcAttr{\n\t\tSetpgid: true,\n\t}\n}\n\nfunc openPty() (*os.File, *os.File, error) {\n\treturn pty.Open()\n}\n"
  },
  {
    "path": "pkg/container/util_openbsd_mips64.go",
    "content": "package container\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc getSysProcAttr(cmdLine string, tty bool) *syscall.SysProcAttr {\n\treturn &syscall.SysProcAttr{\n\t\tSetpgid: true,\n\t}\n}\n\nfunc openPty() (*os.File, *os.File, error) {\n\treturn nil, nil, errors.New(\"Unsupported\")\n}\n"
  },
  {
    "path": "pkg/container/util_plan9.go",
    "content": "package container\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc getSysProcAttr(cmdLine string, tty bool) *syscall.SysProcAttr {\n\treturn &syscall.SysProcAttr{\n\t\tRfork: syscall.RFNOTEG,\n\t}\n}\n\nfunc openPty() (*os.File, *os.File, error) {\n\treturn nil, nil, errors.New(\"Unsupported\")\n}\n"
  },
  {
    "path": "pkg/container/util_windows.go",
    "content": "package container\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc getSysProcAttr(cmdLine string, tty bool) *syscall.SysProcAttr {\n\treturn &syscall.SysProcAttr{CmdLine: cmdLine, CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP}\n}\n\nfunc openPty() (*os.File, *os.File, error) {\n\treturn nil, nil, errors.New(\"Unsupported\")\n}\n"
  },
  {
    "path": "pkg/exprparser/functions.go",
    "content": "package exprparser\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/go-git/go-git/v5/plumbing/format/gitignore\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/rhysd/actionlint\"\n)\n\nfunc (impl *interperterImpl) contains(search, item reflect.Value) (bool, error) {\n\tswitch search.Kind() {\n\tcase reflect.String, reflect.Int, reflect.Float64, reflect.Bool, reflect.Invalid:\n\t\treturn strings.Contains(\n\t\t\tstrings.ToLower(impl.coerceToString(search).String()),\n\t\t\tstrings.ToLower(impl.coerceToString(item).String()),\n\t\t), nil\n\n\tcase reflect.Slice:\n\t\tfor i := 0; i < search.Len(); i++ {\n\t\t\tarrayItem := search.Index(i).Elem()\n\t\t\tresult, err := impl.compareValues(arrayItem, item, actionlint.CompareOpNodeKindEq)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\n\t\t\tif isEqual, ok := result.(bool); ok && isEqual {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, nil\n}\n\nfunc (impl *interperterImpl) startsWith(searchString, searchValue reflect.Value) (bool, error) {\n\treturn strings.HasPrefix(\n\t\tstrings.ToLower(impl.coerceToString(searchString).String()),\n\t\tstrings.ToLower(impl.coerceToString(searchValue).String()),\n\t), nil\n}\n\nfunc (impl *interperterImpl) endsWith(searchString, searchValue reflect.Value) (bool, error) {\n\treturn strings.HasSuffix(\n\t\tstrings.ToLower(impl.coerceToString(searchString).String()),\n\t\tstrings.ToLower(impl.coerceToString(searchValue).String()),\n\t), nil\n}\n\nconst (\n\tpassThrough = iota\n\tbracketOpen\n\tbracketClose\n)\n\nfunc (impl *interperterImpl) format(str reflect.Value, replaceValue ...reflect.Value) (string, error) {\n\tinput := impl.coerceToString(str).String()\n\toutput := \"\"\n\treplacementIndex := \"\"\n\n\tstate := passThrough\n\tfor _, character := range input {\n\t\tswitch state {\n\t\tcase passThrough: // normal buffer output\n\t\t\tswitch character {\n\t\t\tcase '{':\n\t\t\t\tstate = bracketOpen\n\n\t\t\tcase '}':\n\t\t\t\tstate = bracketClose\n\n\t\t\tdefault:\n\t\t\t\toutput += string(character)\n\t\t\t}\n\n\t\tcase bracketOpen: // found {\n\t\t\tswitch character {\n\t\t\tcase '{':\n\t\t\t\toutput += \"{\"\n\t\t\t\treplacementIndex = \"\"\n\t\t\t\tstate = passThrough\n\n\t\t\tcase '}':\n\t\t\t\tindex, err := strconv.ParseInt(replacementIndex, 10, 32)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn \"\", fmt.Errorf(\"The following format string is invalid: '%s'\", input)\n\t\t\t\t}\n\n\t\t\t\treplacementIndex = \"\"\n\n\t\t\t\tif len(replaceValue) <= int(index) {\n\t\t\t\t\treturn \"\", fmt.Errorf(\"The following format string references more arguments than were supplied: '%s'\", input)\n\t\t\t\t}\n\n\t\t\t\toutput += impl.coerceToString(replaceValue[index]).String()\n\n\t\t\t\tstate = passThrough\n\n\t\t\tdefault:\n\t\t\t\treplacementIndex += string(character)\n\t\t\t}\n\n\t\tcase bracketClose: // found }\n\t\t\tswitch character {\n\t\t\tcase '}':\n\t\t\t\toutput += \"}\"\n\t\t\t\treplacementIndex = \"\"\n\t\t\t\tstate = passThrough\n\n\t\t\tdefault:\n\t\t\t\tpanic(\"Invalid format parser state\")\n\t\t\t}\n\t\t}\n\t}\n\n\tif state != passThrough {\n\t\tswitch state {\n\t\tcase bracketOpen:\n\t\t\treturn \"\", fmt.Errorf(\"Unclosed brackets. The following format string is invalid: '%s'\", input)\n\n\t\tcase bracketClose:\n\t\t\treturn \"\", fmt.Errorf(\"Closing bracket without opening one. The following format string is invalid: '%s'\", input)\n\t\t}\n\t}\n\n\treturn output, nil\n}\n\nfunc (impl *interperterImpl) join(array reflect.Value, sep reflect.Value) (string, error) {\n\tseparator := impl.coerceToString(sep).String()\n\tswitch array.Kind() {\n\tcase reflect.Slice:\n\t\tvar items []string\n\t\tfor i := 0; i < array.Len(); i++ {\n\t\t\titems = append(items, impl.coerceToString(array.Index(i).Elem()).String())\n\t\t}\n\n\t\treturn strings.Join(items, separator), nil\n\tdefault:\n\t\treturn strings.Join([]string{impl.coerceToString(array).String()}, separator), nil\n\t}\n}\n\nfunc (impl *interperterImpl) toJSON(value reflect.Value) (string, error) {\n\tif value.Kind() == reflect.Invalid {\n\t\treturn \"null\", nil\n\t}\n\n\tjson, err := json.MarshalIndent(value.Interface(), \"\", \"  \")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Cannot convert value to JSON. Cause: %v\", err)\n\t}\n\n\treturn string(json), nil\n}\n\nfunc (impl *interperterImpl) fromJSON(value reflect.Value) (interface{}, error) {\n\tif value.Kind() != reflect.String {\n\t\treturn nil, fmt.Errorf(\"Cannot parse non-string type %v as JSON\", value.Kind())\n\t}\n\n\tvar data interface{}\n\n\terr := json.Unmarshal([]byte(value.String()), &data)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Invalid JSON: %v\", err)\n\t}\n\n\treturn data, nil\n}\n\nfunc (impl *interperterImpl) hashFiles(paths ...reflect.Value) (string, error) {\n\tvar ps []gitignore.Pattern\n\n\tconst cwdPrefix = \".\" + string(filepath.Separator)\n\tconst excludeCwdPrefix = \"!\" + cwdPrefix\n\tfor _, path := range paths {\n\t\tif path.Kind() == reflect.String {\n\t\t\tcleanPath := path.String()\n\t\t\tif strings.HasPrefix(cleanPath, cwdPrefix) {\n\t\t\t\tcleanPath = cleanPath[len(cwdPrefix):]\n\t\t\t} else if strings.HasPrefix(cleanPath, excludeCwdPrefix) {\n\t\t\t\tcleanPath = \"!\" + cleanPath[len(excludeCwdPrefix):]\n\t\t\t}\n\t\t\tps = append(ps, gitignore.ParsePattern(cleanPath, nil))\n\t\t} else {\n\t\t\treturn \"\", fmt.Errorf(\"Non-string path passed to hashFiles\")\n\t\t}\n\t}\n\n\tmatcher := gitignore.NewMatcher(ps)\n\n\tvar files []string\n\tif err := filepath.Walk(impl.config.WorkingDir, func(path string, fi fs.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsansPrefix := strings.TrimPrefix(path, impl.config.WorkingDir+string(filepath.Separator))\n\t\tparts := strings.Split(sansPrefix, string(filepath.Separator))\n\t\tif fi.IsDir() || !matcher.Match(parts, fi.IsDir()) {\n\t\t\treturn nil\n\t\t}\n\t\tfiles = append(files, path)\n\t\treturn nil\n\t}); err != nil {\n\t\treturn \"\", fmt.Errorf(\"Unable to filepath.Walk: %v\", err)\n\t}\n\n\tif len(files) == 0 {\n\t\treturn \"\", nil\n\t}\n\n\thasher := sha256.New()\n\n\tfor _, file := range files {\n\t\tf, err := os.Open(file)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Unable to os.Open: %v\", err)\n\t\t}\n\n\t\tif _, err := io.Copy(hasher, f); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Unable to io.Copy: %v\", err)\n\t\t}\n\n\t\tif err := f.Close(); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Unable to Close file: %v\", err)\n\t\t}\n\t}\n\n\treturn hex.EncodeToString(hasher.Sum(nil)), nil\n}\n\nfunc (impl *interperterImpl) getNeedsTransitive(job *model.Job) []string {\n\tneeds := job.Needs()\n\n\tfor _, need := range needs {\n\t\tparentNeeds := impl.getNeedsTransitive(impl.config.Run.Workflow.GetJob(need))\n\t\tneeds = append(needs, parentNeeds...)\n\t}\n\n\treturn needs\n}\n\nfunc (impl *interperterImpl) always() (bool, error) {\n\treturn true, nil\n}\n\nfunc (impl *interperterImpl) jobSuccess() (bool, error) {\n\tjobs := impl.config.Run.Workflow.Jobs\n\tjobNeeds := impl.getNeedsTransitive(impl.config.Run.Job())\n\n\tfor _, needs := range jobNeeds {\n\t\tif jobs[needs].Result != \"success\" {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\n\treturn true, nil\n}\n\nfunc (impl *interperterImpl) stepSuccess() (bool, error) {\n\treturn impl.env.Job.Status == \"success\", nil\n}\n\nfunc (impl *interperterImpl) jobFailure() (bool, error) {\n\tjobs := impl.config.Run.Workflow.Jobs\n\tjobNeeds := impl.getNeedsTransitive(impl.config.Run.Job())\n\n\tfor _, needs := range jobNeeds {\n\t\tif jobs[needs].Result == \"failure\" {\n\t\t\treturn true, nil\n\t\t}\n\t}\n\n\treturn false, nil\n}\n\nfunc (impl *interperterImpl) stepFailure() (bool, error) {\n\treturn impl.env.Job.Status == \"failure\", nil\n}\n\nfunc (impl *interperterImpl) cancelled() (bool, error) {\n\treturn impl.env.Job.Status == \"cancelled\", nil\n}\n"
  },
  {
    "path": "pkg/exprparser/functions_test.go",
    "content": "package exprparser\n\nimport (\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestFunctionContains(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"contains('search', 'item') }}\", false, \"contains-str-str\"},\n\t\t{`cOnTaInS('Hello', 'll') }}`, true, \"contains-str-casing\"},\n\t\t{`contains('HELLO', 'll') }}`, true, \"contains-str-casing\"},\n\t\t{`contains('3.141592', 3.14) }}`, true, \"contains-str-number\"},\n\t\t{`contains(3.141592, '3.14') }}`, true, \"contains-number-str\"},\n\t\t{`contains(3.141592, 3.14) }}`, true, \"contains-number-number\"},\n\t\t{`contains(true, 'u') }}`, true, \"contains-bool-str\"},\n\t\t{`contains(null, '') }}`, true, \"contains-null-str\"},\n\t\t{`contains(fromJSON('[\"first\",\"second\"]'), 'first') }}`, true, \"contains-item\"},\n\t\t{`contains(fromJSON('[null,\"second\"]'), '') }}`, true, \"contains-item-null-empty-str\"},\n\t\t{`contains(fromJSON('[\"\",\"second\"]'), null) }}`, true, \"contains-item-empty-str-null\"},\n\t\t{`contains(fromJSON('[true,\"second\"]'), 'true') }}`, false, \"contains-item-bool-arr\"},\n\t\t{`contains(fromJSON('[\"true\",\"second\"]'), true) }}`, false, \"contains-item-str-bool\"},\n\t\t{`contains(fromJSON('[3.14,\"second\"]'), '3.14') }}`, true, \"contains-item-number-str\"},\n\t\t{`contains(fromJSON('[3.14,\"second\"]'), 3.14) }}`, true, \"contains-item-number-number\"},\n\t\t{`contains(fromJSON('[\"\",\"second\"]'), fromJSON('[]')) }}`, false, \"contains-item-str-arr\"},\n\t\t{`contains(fromJSON('[\"\",\"second\"]'), fromJSON('{}')) }}`, false, \"contains-item-str-obj\"},\n\t\t{`contains(fromJSON('[{ \"first\": { \"result\": \"success\" }},{ \"second\": { \"result\": \"success\" }}]').first.result, 'success') }}`, true, \"multiple-contains-item\"},\n\t\t{`contains(fromJSON('[{ \"result\": \"success\" },{ \"result\": \"failure\" }]').*.result, 'failure') }}`, true, \"multiple-contains-dereferenced-failure-item\"},\n\t\t{`contains(fromJSON('[{ \"result\": \"failure\" },{ \"result\": \"success\" }]').*.result, 'success') }}`, true, \"multiple-contains-dereferenced-success-item\"},\n\t\t{`contains(fromJSON('[{ \"result\": \"failure\" },{ \"result\": \"success\" }]').*.result, 'notthere') }}`, false, \"multiple-contains-dereferenced-missing-item\"},\n\t\t{`contains(fromJSON('[{ \"result\": \"failure\", \"outputs\": { \"key\": \"val1\" } },{ \"result\": \"success\", \"outputs\": { \"key\": \"val2\" } }]').*.outputs.key, 'val1') }}`, true, \"multiple-contains-dereferenced-output-item\"},\n\t\t{`contains(fromJSON('[{ \"result\": \"failure\", \"outputs\": { \"key\": \"val1\" } },{ \"result\": \"success\", \"outputs\": { \"key\": \"val2\" } }]').*.outputs.key, 'val2') }}`, true, \"multiple-contains-dereferenced-output-item-2\"},\n\t\t{`contains(fromJSON('[{ \"result\": \"failure\", \"outputs\": { \"key\": \"val1\" } },{ \"result\": \"success\", \"outputs\": { \"key\": \"val2\" } }]').*.outputs.key, 'missing') }}`, false, \"multiple-contains-dereferenced-output-misssing-item\"},\n\t}\n\n\tenv := &EvaluationEnvironment{}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestFunctionStartsWith(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"startsWith('search', 'se') }}\", true, \"startswith-string\"},\n\t\t{\"startsWith('search', 'sa') }}\", false, \"startswith-string\"},\n\t\t{\"startsWith('123search', '123s') }}\", true, \"startswith-string\"},\n\t\t{\"startsWith(123, 's') }}\", false, \"startswith-string\"},\n\t\t{\"startsWith(123, '12') }}\", true, \"startswith-string\"},\n\t\t{\"startsWith('123', 12) }}\", true, \"startswith-string\"},\n\t\t{\"startsWith(null, '42') }}\", false, \"startswith-string\"},\n\t\t{\"startsWith('null', null) }}\", true, \"startswith-string\"},\n\t\t{\"startsWith('null', '') }}\", true, \"startswith-string\"},\n\t}\n\n\tenv := &EvaluationEnvironment{}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestFunctionEndsWith(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"endsWith('search', 'ch') }}\", true, \"endsWith-string\"},\n\t\t{\"endsWith('search', 'sa') }}\", false, \"endsWith-string\"},\n\t\t{\"endsWith('search123s', '123s') }}\", true, \"endsWith-string\"},\n\t\t{\"endsWith(123, 's') }}\", false, \"endsWith-string\"},\n\t\t{\"endsWith(123, '23') }}\", true, \"endsWith-string\"},\n\t\t{\"endsWith('123', 23) }}\", true, \"endsWith-string\"},\n\t\t{\"endsWith(null, '42') }}\", false, \"endsWith-string\"},\n\t\t{\"endsWith('null', null) }}\", true, \"endsWith-string\"},\n\t\t{\"endsWith('null', '') }}\", true, \"endsWith-string\"},\n\t}\n\n\tenv := &EvaluationEnvironment{}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestFunctionJoin(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"join(fromJSON('[\\\"a\\\", \\\"b\\\"]'), ',')\", \"a,b\", \"join-arr\"},\n\t\t{\"join('string', ',')\", \"string\", \"join-str\"},\n\t\t{\"join(1, ',')\", \"1\", \"join-number\"},\n\t\t{\"join(null, ',')\", \"\", \"join-number\"},\n\t\t{\"join(fromJSON('[\\\"a\\\", \\\"b\\\", null]'), null)\", \"ab\", \"join-number\"},\n\t\t{\"join(fromJSON('[\\\"a\\\", \\\"b\\\"]'))\", \"a,b\", \"join-number\"},\n\t\t{\"join(fromJSON('[\\\"a\\\", \\\"b\\\", null]'), 1)\", \"a1b1\", \"join-number\"},\n\t}\n\n\tenv := &EvaluationEnvironment{}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestFunctionToJSON(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"toJSON(env) }}\", \"{\\n  \\\"key\\\": \\\"value\\\"\\n}\", \"toJSON\"},\n\t\t{\"toJSON(null)\", \"null\", \"toJSON-null\"},\n\t}\n\n\tenv := &EvaluationEnvironment{\n\t\tEnv: map[string]string{\n\t\t\t\"key\": \"value\",\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestFunctionFromJSON(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"fromJSON('{\\\"foo\\\":\\\"bar\\\"}') }}\", map[string]interface{}{\n\t\t\t\"foo\": \"bar\",\n\t\t}, \"fromJSON\"},\n\t}\n\n\tenv := &EvaluationEnvironment{}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestFunctionHashFiles(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"hashFiles('**/non-extant-files') }}\", \"\", \"hash-non-existing-file\"},\n\t\t{\"hashFiles('**/non-extant-files', '**/more-non-extant-files') }}\", \"\", \"hash-multiple-non-existing-files\"},\n\t\t{\"hashFiles('./for-hashing-1.txt') }}\", \"66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18\", \"hash-single-file\"},\n\t\t{\"hashFiles('./for-hashing-*.txt') }}\", \"8e5935e7e13368cd9688fe8f48a0955293676a021562582c7e848dafe13fb046\", \"hash-multiple-files\"},\n\t\t{\"hashFiles('./for-hashing-*.txt', '!./for-hashing-2.txt') }}\", \"66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18\", \"hash-negative-pattern\"},\n\t\t{\"hashFiles('./for-hashing-**') }}\", \"c418ba693753c84115ced0da77f876cddc662b9054f4b129b90f822597ee2f94\", \"hash-multiple-files-and-directories\"},\n\t\t{\"hashFiles('./for-hashing-3/**') }}\", \"6f5696b546a7a9d6d42a449dc9a56bef244aaa826601ef27466168846139d2c2\", \"hash-nested-directories\"},\n\t\t{\"hashFiles('./for-hashing-3/**/nested-data.txt') }}\", \"8ecadfb49f7f978d0a9f3a957e9c8da6cc9ab871f5203b5d9f9d1dc87d8af18c\", \"hash-nested-directories-2\"},\n\t}\n\n\tenv := &EvaluationEnvironment{}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tworkdir, err := filepath.Abs(\"testdata\")\n\t\t\tassert.Nil(t, err)\n\t\t\toutput, err := NewInterpeter(env, Config{WorkingDir: workdir}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestFunctionFormat(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\terror    interface{}\n\t\tname     string\n\t}{\n\t\t{\"format('text')\", \"text\", nil, \"format-plain-string\"},\n\t\t{\"format('Hello {0} {1} {2}!', 'Mona', 'the', 'Octocat')\", \"Hello Mona the Octocat!\", nil, \"format-with-placeholders\"},\n\t\t{\"format('{{Hello {0} {1} {2}!}}', 'Mona', 'the', 'Octocat')\", \"{Hello Mona the Octocat!}\", nil, \"format-with-escaped-braces\"},\n\t\t{\"format('{{0}}', 'test')\", \"{0}\", nil, \"format-with-escaped-braces\"},\n\t\t{\"format('{{{0}}}', 'test')\", \"{test}\", nil, \"format-with-escaped-braces-and-value\"},\n\t\t{\"format('}}')\", \"}\", nil, \"format-output-closing-brace\"},\n\t\t{`format('Hello \"{0}\" {1} {2} {3} {4}', null, true, -3.14, NaN, Infinity)`, `Hello \"\" true -3.14 NaN Infinity`, nil, \"format-with-primitives\"},\n\t\t{`format('Hello \"{0}\" {1} {2}', fromJSON('[0, true, \"abc\"]'), fromJSON('[{\"a\":1}]'), fromJSON('{\"a\":{\"b\":1}}'))`, `Hello \"Array\" Array Object`, nil, \"format-with-complex-types\"},\n\t\t{\"format(true)\", \"true\", nil, \"format-with-primitive-args\"},\n\t\t{\"format('echo Hello {0} ${{Test}}', github.undefined_property)\", \"echo Hello  ${Test}\", nil, \"format-with-undefined-value\"},\n\t\t{\"format('{0}}', '{1}', 'World')\", nil, \"Closing bracket without opening one. The following format string is invalid: '{0}}'\", \"format-invalid-format-string\"},\n\t\t{\"format('{0', '{1}', 'World')\", nil, \"Unclosed brackets. The following format string is invalid: '{0'\", \"format-invalid-format-string\"},\n\t\t{\"format('{2}', '{1}', 'World')\", \"\", \"The following format string references more arguments than were supplied: '{2}'\", \"format-invalid-replacement-reference\"},\n\t\t{\"format('{2147483648}')\", \"\", \"The following format string is invalid: '{2147483648}'\", \"format-invalid-replacement-reference\"},\n\t\t{\"format('{0} {1} {2} {3}', 1.0, 1.1, 1234567890.0, 12345678901234567890.0)\", \"1 1.1 1234567890 1.23456789012346E+19\", nil, \"format-floats\"},\n\t}\n\n\tenv := &EvaluationEnvironment{\n\t\tGithub: &model.GithubContext{},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tif tt.error != nil {\n\t\t\t\tassert.Equal(t, tt.error, err.Error())\n\t\t\t} else {\n\t\t\t\tassert.Nil(t, err)\n\t\t\t\tassert.Equal(t, tt.expected, output)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestMapContains(t *testing.T) {\n\tenv := &EvaluationEnvironment{\n\t\tNeeds: map[string]Needs{\n\t\t\t\"first-job\": {\n\t\t\t\tOutputs: map[string]string{},\n\t\t\t\tResult:  \"success\",\n\t\t\t},\n\t\t\t\"second-job\": {\n\t\t\t\tOutputs: map[string]string{},\n\t\t\t\tResult:  \"failure\",\n\t\t\t},\n\t\t},\n\t}\n\n\toutput, err := NewInterpeter(env, Config{}).Evaluate(\"contains(needs.*.result, 'failure')\", DefaultStatusCheckNone)\n\tassert.Nil(t, err)\n\n\tassert.Equal(t, true, output)\n}\n"
  },
  {
    "path": "pkg/exprparser/interpreter.go",
    "content": "package exprparser\n\nimport (\n\t\"encoding\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/rhysd/actionlint\"\n)\n\ntype EvaluationEnvironment struct {\n\tGithub    *model.GithubContext\n\tEnv       map[string]string\n\tJob       *model.JobContext\n\tJobs      *map[string]*model.WorkflowCallResult\n\tSteps     map[string]*model.StepResult\n\tRunner    map[string]interface{}\n\tSecrets   map[string]string\n\tVars      map[string]string\n\tStrategy  map[string]interface{}\n\tMatrix    map[string]interface{}\n\tNeeds     map[string]Needs\n\tInputs    map[string]interface{}\n\tHashFiles func([]reflect.Value) (interface{}, error)\n}\n\ntype Needs struct {\n\tOutputs map[string]string `json:\"outputs\"`\n\tResult  string            `json:\"result\"`\n}\n\ntype Config struct {\n\tRun        *model.Run\n\tWorkingDir string\n\tContext    string\n}\n\ntype DefaultStatusCheck int\n\nconst (\n\tDefaultStatusCheckNone DefaultStatusCheck = iota\n\tDefaultStatusCheckSuccess\n\tDefaultStatusCheckAlways\n\tDefaultStatusCheckCanceled\n\tDefaultStatusCheckFailure\n)\n\nfunc (dsc DefaultStatusCheck) String() string {\n\tswitch dsc {\n\tcase DefaultStatusCheckSuccess:\n\t\treturn \"success\"\n\tcase DefaultStatusCheckAlways:\n\t\treturn \"always\"\n\tcase DefaultStatusCheckCanceled:\n\t\treturn \"cancelled\"\n\tcase DefaultStatusCheckFailure:\n\t\treturn \"failure\"\n\t}\n\treturn \"\"\n}\n\ntype Interpreter interface {\n\tEvaluate(input string, defaultStatusCheck DefaultStatusCheck) (interface{}, error)\n}\n\ntype interperterImpl struct {\n\tenv    *EvaluationEnvironment\n\tconfig Config\n}\n\nfunc NewInterpeter(env *EvaluationEnvironment, config Config) Interpreter {\n\treturn &interperterImpl{\n\t\tenv:    env,\n\t\tconfig: config,\n\t}\n}\n\nfunc (impl *interperterImpl) Evaluate(input string, defaultStatusCheck DefaultStatusCheck) (interface{}, error) {\n\tinput = strings.TrimPrefix(input, \"${{\")\n\tif defaultStatusCheck != DefaultStatusCheckNone && input == \"\" {\n\t\tinput = \"success()\"\n\t}\n\tparser := actionlint.NewExprParser()\n\texprNode, err := parser.Parse(actionlint.NewExprLexer(input + \"}}\"))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Failed to parse: %s\", err.Message)\n\t}\n\n\tif defaultStatusCheck != DefaultStatusCheckNone {\n\t\thasStatusCheckFunction := false\n\t\tactionlint.VisitExprNode(exprNode, func(node, _ actionlint.ExprNode, entering bool) {\n\t\t\tif funcCallNode, ok := node.(*actionlint.FuncCallNode); entering && ok {\n\t\t\t\tswitch strings.ToLower(funcCallNode.Callee) {\n\t\t\t\tcase \"success\", \"always\", \"cancelled\", \"failure\":\n\t\t\t\t\thasStatusCheckFunction = true\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tif !hasStatusCheckFunction {\n\t\t\texprNode = &actionlint.LogicalOpNode{\n\t\t\t\tKind: actionlint.LogicalOpNodeKindAnd,\n\t\t\t\tLeft: &actionlint.FuncCallNode{\n\t\t\t\t\tCallee: defaultStatusCheck.String(),\n\t\t\t\t\tArgs:   []actionlint.ExprNode{},\n\t\t\t\t},\n\t\t\t\tRight: exprNode,\n\t\t\t}\n\t\t}\n\t}\n\n\tresult, err2 := impl.evaluateNode(exprNode)\n\n\treturn result, err2\n}\n\nfunc (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interface{}, error) {\n\tswitch node := exprNode.(type) {\n\tcase *actionlint.VariableNode:\n\t\treturn impl.evaluateVariable(node)\n\tcase *actionlint.BoolNode:\n\t\treturn node.Value, nil\n\tcase *actionlint.NullNode:\n\t\treturn nil, nil\n\tcase *actionlint.IntNode:\n\t\treturn node.Value, nil\n\tcase *actionlint.FloatNode:\n\t\treturn node.Value, nil\n\tcase *actionlint.StringNode:\n\t\treturn node.Value, nil\n\tcase *actionlint.IndexAccessNode:\n\t\treturn impl.evaluateIndexAccess(node)\n\tcase *actionlint.ObjectDerefNode:\n\t\treturn impl.evaluateObjectDeref(node)\n\tcase *actionlint.ArrayDerefNode:\n\t\treturn impl.evaluateArrayDeref(node)\n\tcase *actionlint.NotOpNode:\n\t\treturn impl.evaluateNot(node)\n\tcase *actionlint.CompareOpNode:\n\t\treturn impl.evaluateCompare(node)\n\tcase *actionlint.LogicalOpNode:\n\t\treturn impl.evaluateLogicalCompare(node)\n\tcase *actionlint.FuncCallNode:\n\t\treturn impl.evaluateFuncCall(node)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"Fatal error! Unknown node type: %s node: %+v\", reflect.TypeOf(exprNode), exprNode)\n\t}\n}\n\nfunc (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableNode) (interface{}, error) {\n\tswitch strings.ToLower(variableNode.Name) {\n\tcase \"github\":\n\t\treturn impl.env.Github, nil\n\tcase \"env\":\n\t\treturn impl.env.Env, nil\n\tcase \"job\":\n\t\treturn impl.env.Job, nil\n\tcase \"jobs\":\n\t\tif impl.env.Jobs == nil {\n\t\t\treturn nil, fmt.Errorf(\"Unavailable context: jobs\")\n\t\t}\n\t\treturn impl.env.Jobs, nil\n\tcase \"steps\":\n\t\treturn impl.env.Steps, nil\n\tcase \"runner\":\n\t\treturn impl.env.Runner, nil\n\tcase \"secrets\":\n\t\treturn impl.env.Secrets, nil\n\tcase \"vars\":\n\t\treturn impl.env.Vars, nil\n\tcase \"strategy\":\n\t\treturn impl.env.Strategy, nil\n\tcase \"matrix\":\n\t\treturn impl.env.Matrix, nil\n\tcase \"needs\":\n\t\treturn impl.env.Needs, nil\n\tcase \"inputs\":\n\t\treturn impl.env.Inputs, nil\n\tcase \"infinity\":\n\t\treturn math.Inf(1), nil\n\tcase \"nan\":\n\t\treturn math.NaN(), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"Unavailable context: %s\", variableNode.Name)\n\t}\n}\n\nfunc (impl *interperterImpl) evaluateIndexAccess(indexAccessNode *actionlint.IndexAccessNode) (interface{}, error) {\n\tleft, err := impl.evaluateNode(indexAccessNode.Operand)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tleftValue := reflect.ValueOf(left)\n\n\tright, err := impl.evaluateNode(indexAccessNode.Index)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trightValue := reflect.ValueOf(right)\n\n\tswitch rightValue.Kind() {\n\tcase reflect.String:\n\t\treturn impl.getPropertyValue(leftValue, rightValue.String())\n\n\tcase reflect.Int:\n\t\tswitch leftValue.Kind() {\n\t\tcase reflect.Slice:\n\t\t\tif rightValue.Int() < 0 || rightValue.Int() >= int64(leftValue.Len()) {\n\t\t\t\treturn nil, nil\n\t\t\t}\n\t\t\treturn leftValue.Index(int(rightValue.Int())).Interface(), nil\n\t\tdefault:\n\t\t\treturn nil, nil\n\t\t}\n\n\tdefault:\n\t\treturn nil, nil\n\t}\n}\n\nfunc (impl *interperterImpl) evaluateObjectDeref(objectDerefNode *actionlint.ObjectDerefNode) (interface{}, error) {\n\tleft, err := impl.evaluateNode(objectDerefNode.Receiver)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, receiverIsDeref := objectDerefNode.Receiver.(*actionlint.ArrayDerefNode)\n\tif receiverIsDeref {\n\t\treturn impl.getPropertyValueDereferenced(reflect.ValueOf(left), objectDerefNode.Property)\n\t}\n\treturn impl.getPropertyValue(reflect.ValueOf(left), objectDerefNode.Property)\n}\n\nfunc (impl *interperterImpl) evaluateArrayDeref(arrayDerefNode *actionlint.ArrayDerefNode) (interface{}, error) {\n\tleft, err := impl.evaluateNode(arrayDerefNode.Receiver)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn impl.getSafeValue(reflect.ValueOf(left)), nil\n}\n\nfunc (impl *interperterImpl) getPropertyValue(left reflect.Value, property string) (value interface{}, err error) {\n\tswitch left.Kind() {\n\tcase reflect.Ptr:\n\t\treturn impl.getPropertyValue(left.Elem(), property)\n\n\tcase reflect.Struct:\n\t\tleftType := left.Type()\n\t\tfor i := 0; i < leftType.NumField(); i++ {\n\t\t\tjsonName := leftType.Field(i).Tag.Get(\"json\")\n\t\t\tif jsonName == property {\n\t\t\t\tproperty = leftType.Field(i).Name\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tfieldValue := left.FieldByNameFunc(func(name string) bool {\n\t\t\treturn strings.EqualFold(name, property)\n\t\t})\n\n\t\tif fieldValue.Kind() == reflect.Invalid {\n\t\t\treturn \"\", nil\n\t\t}\n\n\t\ti := fieldValue.Interface()\n\t\t// The type stepStatus int is an integer, but should be treated as string\n\t\tif m, ok := i.(encoding.TextMarshaler); ok {\n\t\t\ttext, err := m.MarshalText()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn string(text), nil\n\t\t}\n\t\treturn i, nil\n\n\tcase reflect.Map:\n\t\titer := left.MapRange()\n\n\t\tfor iter.Next() {\n\t\t\tkey := iter.Key()\n\n\t\t\tswitch key.Kind() {\n\t\t\tcase reflect.String:\n\t\t\t\tif strings.EqualFold(key.String(), property) {\n\t\t\t\t\treturn impl.getMapValue(iter.Value())\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"'%s' in map key not implemented\", key.Kind())\n\t\t\t}\n\t\t}\n\n\t\treturn nil, nil\n\n\tcase reflect.Slice:\n\t\tvar values []interface{}\n\n\t\tfor i := 0; i < left.Len(); i++ {\n\t\t\tvalue, err := impl.getPropertyValue(left.Index(i).Elem(), property)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tvalues = append(values, value)\n\t\t}\n\n\t\treturn values, nil\n\t}\n\n\treturn nil, nil\n}\n\nfunc (impl *interperterImpl) getPropertyValueDereferenced(left reflect.Value, property string) (value interface{}, err error) {\n\tswitch left.Kind() {\n\tcase reflect.Ptr:\n\t\treturn impl.getPropertyValue(left, property)\n\n\tcase reflect.Struct:\n\t\treturn impl.getPropertyValue(left, property)\n\tcase reflect.Map:\n\t\titer := left.MapRange()\n\n\t\tvar values []interface{}\n\t\tfor iter.Next() {\n\t\t\tvalue, err := impl.getPropertyValue(iter.Value(), property)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tvalues = append(values, value)\n\t\t}\n\n\t\treturn values, nil\n\tcase reflect.Slice:\n\t\treturn impl.getPropertyValue(left, property)\n\t}\n\n\treturn nil, nil\n}\n\nfunc (impl *interperterImpl) getMapValue(value reflect.Value) (interface{}, error) {\n\tif value.Kind() == reflect.Ptr {\n\t\treturn impl.getMapValue(value.Elem())\n\t}\n\n\treturn value.Interface(), nil\n}\n\nfunc (impl *interperterImpl) evaluateNot(notNode *actionlint.NotOpNode) (interface{}, error) {\n\toperand, err := impl.evaluateNode(notNode.Operand)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn !IsTruthy(operand), nil\n}\n\nfunc (impl *interperterImpl) evaluateCompare(compareNode *actionlint.CompareOpNode) (interface{}, error) {\n\tleft, err := impl.evaluateNode(compareNode.Left)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tright, err := impl.evaluateNode(compareNode.Right)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tleftValue := reflect.ValueOf(left)\n\trightValue := reflect.ValueOf(right)\n\n\treturn impl.compareValues(leftValue, rightValue, compareNode.Kind)\n}\n\nfunc (impl *interperterImpl) compareValues(leftValue reflect.Value, rightValue reflect.Value, kind actionlint.CompareOpNodeKind) (interface{}, error) {\n\tif leftValue.Kind() != rightValue.Kind() {\n\t\tif !impl.isNumber(leftValue) {\n\t\t\tleftValue = impl.coerceToNumber(leftValue)\n\t\t}\n\t\tif !impl.isNumber(rightValue) {\n\t\t\trightValue = impl.coerceToNumber(rightValue)\n\t\t}\n\t}\n\n\tswitch leftValue.Kind() {\n\tcase reflect.Bool:\n\t\treturn impl.compareNumber(float64(impl.coerceToNumber(leftValue).Int()), float64(impl.coerceToNumber(rightValue).Int()), kind)\n\tcase reflect.String:\n\t\treturn impl.compareString(strings.ToLower(leftValue.String()), strings.ToLower(rightValue.String()), kind)\n\n\tcase reflect.Int:\n\t\tif rightValue.Kind() == reflect.Float64 {\n\t\t\treturn impl.compareNumber(float64(leftValue.Int()), rightValue.Float(), kind)\n\t\t}\n\n\t\treturn impl.compareNumber(float64(leftValue.Int()), float64(rightValue.Int()), kind)\n\n\tcase reflect.Float64:\n\t\tif rightValue.Kind() == reflect.Int {\n\t\t\treturn impl.compareNumber(leftValue.Float(), float64(rightValue.Int()), kind)\n\t\t}\n\n\t\treturn impl.compareNumber(leftValue.Float(), rightValue.Float(), kind)\n\n\tcase reflect.Invalid:\n\t\tif rightValue.Kind() == reflect.Invalid {\n\t\t\treturn true, nil\n\t\t}\n\n\t\t// not possible situation - params are converted to the same type in code above\n\t\treturn nil, fmt.Errorf(\"Compare params of Invalid type: left: %+v, right: %+v\", leftValue.Kind(), rightValue.Kind())\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"Compare not implemented for types: left: %+v, right: %+v\", leftValue.Kind(), rightValue.Kind())\n\t}\n}\n\nfunc (impl *interperterImpl) coerceToNumber(value reflect.Value) reflect.Value {\n\tswitch value.Kind() {\n\tcase reflect.Invalid:\n\t\treturn reflect.ValueOf(0)\n\n\tcase reflect.Bool:\n\t\tswitch value.Bool() {\n\t\tcase true:\n\t\t\treturn reflect.ValueOf(1)\n\t\tcase false:\n\t\t\treturn reflect.ValueOf(0)\n\t\t}\n\n\tcase reflect.String:\n\t\tif value.String() == \"\" {\n\t\t\treturn reflect.ValueOf(0)\n\t\t}\n\n\t\t// try to parse the string as a number\n\t\tevaluated, err := impl.Evaluate(value.String(), DefaultStatusCheckNone)\n\t\tif err != nil {\n\t\t\treturn reflect.ValueOf(math.NaN())\n\t\t}\n\n\t\tif value := reflect.ValueOf(evaluated); impl.isNumber(value) {\n\t\t\treturn value\n\t\t}\n\t}\n\n\treturn reflect.ValueOf(math.NaN())\n}\n\nfunc (impl *interperterImpl) coerceToString(value reflect.Value) reflect.Value {\n\tswitch value.Kind() {\n\tcase reflect.Invalid:\n\t\treturn reflect.ValueOf(\"\")\n\n\tcase reflect.Bool:\n\t\tswitch value.Bool() {\n\t\tcase true:\n\t\t\treturn reflect.ValueOf(\"true\")\n\t\tcase false:\n\t\t\treturn reflect.ValueOf(\"false\")\n\t\t}\n\n\tcase reflect.String:\n\t\treturn value\n\n\tcase reflect.Int:\n\t\treturn reflect.ValueOf(fmt.Sprint(value))\n\n\tcase reflect.Float64:\n\t\tif math.IsInf(value.Float(), 1) {\n\t\t\treturn reflect.ValueOf(\"Infinity\")\n\t\t} else if math.IsInf(value.Float(), -1) {\n\t\t\treturn reflect.ValueOf(\"-Infinity\")\n\t\t}\n\t\treturn reflect.ValueOf(fmt.Sprintf(\"%.15G\", value.Float()))\n\n\tcase reflect.Slice:\n\t\treturn reflect.ValueOf(\"Array\")\n\n\tcase reflect.Map:\n\t\treturn reflect.ValueOf(\"Object\")\n\t}\n\n\treturn value\n}\n\nfunc (impl *interperterImpl) compareString(left string, right string, kind actionlint.CompareOpNodeKind) (bool, error) {\n\tswitch kind {\n\tcase actionlint.CompareOpNodeKindLess:\n\t\treturn left < right, nil\n\tcase actionlint.CompareOpNodeKindLessEq:\n\t\treturn left <= right, nil\n\tcase actionlint.CompareOpNodeKindGreater:\n\t\treturn left > right, nil\n\tcase actionlint.CompareOpNodeKindGreaterEq:\n\t\treturn left >= right, nil\n\tcase actionlint.CompareOpNodeKindEq:\n\t\treturn left == right, nil\n\tcase actionlint.CompareOpNodeKindNotEq:\n\t\treturn left != right, nil\n\tdefault:\n\t\treturn false, fmt.Errorf(\"TODO: not implemented to compare '%+v'\", kind)\n\t}\n}\n\nfunc (impl *interperterImpl) compareNumber(left float64, right float64, kind actionlint.CompareOpNodeKind) (bool, error) {\n\tswitch kind {\n\tcase actionlint.CompareOpNodeKindLess:\n\t\treturn left < right, nil\n\tcase actionlint.CompareOpNodeKindLessEq:\n\t\treturn left <= right, nil\n\tcase actionlint.CompareOpNodeKindGreater:\n\t\treturn left > right, nil\n\tcase actionlint.CompareOpNodeKindGreaterEq:\n\t\treturn left >= right, nil\n\tcase actionlint.CompareOpNodeKindEq:\n\t\treturn left == right, nil\n\tcase actionlint.CompareOpNodeKindNotEq:\n\t\treturn left != right, nil\n\tdefault:\n\t\treturn false, fmt.Errorf(\"TODO: not implemented to compare '%+v'\", kind)\n\t}\n}\n\nfunc IsTruthy(input interface{}) bool {\n\tvalue := reflect.ValueOf(input)\n\tswitch value.Kind() {\n\tcase reflect.Bool:\n\t\treturn value.Bool()\n\n\tcase reflect.String:\n\t\treturn value.String() != \"\"\n\n\tcase reflect.Int:\n\t\treturn value.Int() != 0\n\n\tcase reflect.Float64:\n\t\tif math.IsNaN(value.Float()) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn value.Float() != 0\n\n\tcase reflect.Map, reflect.Slice:\n\t\treturn true\n\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (impl *interperterImpl) isNumber(value reflect.Value) bool {\n\tswitch value.Kind() {\n\tcase reflect.Int, reflect.Float64:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (impl *interperterImpl) getSafeValue(value reflect.Value) interface{} {\n\tswitch value.Kind() {\n\tcase reflect.Invalid:\n\t\treturn nil\n\n\tcase reflect.Float64:\n\t\tif value.Float() == 0 {\n\t\t\treturn 0\n\t\t}\n\t}\n\n\treturn value.Interface()\n}\n\nfunc (impl *interperterImpl) evaluateLogicalCompare(compareNode *actionlint.LogicalOpNode) (interface{}, error) {\n\tleft, err := impl.evaluateNode(compareNode.Left)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tleftValue := reflect.ValueOf(left)\n\n\tif IsTruthy(left) == (compareNode.Kind == actionlint.LogicalOpNodeKindOr) {\n\t\treturn impl.getSafeValue(leftValue), nil\n\t}\n\n\tright, err := impl.evaluateNode(compareNode.Right)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trightValue := reflect.ValueOf(right)\n\n\tswitch compareNode.Kind {\n\tcase actionlint.LogicalOpNodeKindAnd:\n\t\treturn impl.getSafeValue(rightValue), nil\n\tcase actionlint.LogicalOpNodeKindOr:\n\t\treturn impl.getSafeValue(rightValue), nil\n\t}\n\n\treturn nil, fmt.Errorf(\"Unable to compare incompatibles types '%s' and '%s'\", leftValue.Kind(), rightValue.Kind())\n}\n\n//nolint:gocyclo\nfunc (impl *interperterImpl) evaluateFuncCall(funcCallNode *actionlint.FuncCallNode) (interface{}, error) {\n\targs := make([]reflect.Value, 0)\n\n\tfor _, arg := range funcCallNode.Args {\n\t\tvalue, err := impl.evaluateNode(arg)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\targs = append(args, reflect.ValueOf(value))\n\t}\n\n\tswitch strings.ToLower(funcCallNode.Callee) {\n\tcase \"contains\":\n\t\treturn impl.contains(args[0], args[1])\n\tcase \"startswith\":\n\t\treturn impl.startsWith(args[0], args[1])\n\tcase \"endswith\":\n\t\treturn impl.endsWith(args[0], args[1])\n\tcase \"format\":\n\t\treturn impl.format(args[0], args[1:]...)\n\tcase \"join\":\n\t\tif len(args) == 1 {\n\t\t\treturn impl.join(args[0], reflect.ValueOf(\",\"))\n\t\t}\n\t\treturn impl.join(args[0], args[1])\n\tcase \"tojson\":\n\t\treturn impl.toJSON(args[0])\n\tcase \"fromjson\":\n\t\treturn impl.fromJSON(args[0])\n\tcase \"hashfiles\":\n\t\tif impl.env.HashFiles != nil {\n\t\t\treturn impl.env.HashFiles(args)\n\t\t}\n\t\treturn impl.hashFiles(args...)\n\tcase \"always\":\n\t\treturn impl.always()\n\tcase \"success\":\n\t\tif impl.config.Context == \"job\" {\n\t\t\treturn impl.jobSuccess()\n\t\t}\n\t\tif impl.config.Context == \"step\" {\n\t\t\treturn impl.stepSuccess()\n\t\t}\n\t\treturn nil, fmt.Errorf(\"Context '%s' must be one of 'job' or 'step'\", impl.config.Context)\n\tcase \"failure\":\n\t\tif impl.config.Context == \"job\" {\n\t\t\treturn impl.jobFailure()\n\t\t}\n\t\tif impl.config.Context == \"step\" {\n\t\t\treturn impl.stepFailure()\n\t\t}\n\t\treturn nil, fmt.Errorf(\"Context '%s' must be one of 'job' or 'step'\", impl.config.Context)\n\tcase \"cancelled\":\n\t\treturn impl.cancelled()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"TODO: '%s' not implemented\", funcCallNode.Callee)\n\t}\n}\n"
  },
  {
    "path": "pkg/exprparser/interpreter_test.go",
    "content": "package exprparser\n\nimport (\n\t\"math\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestLiterals(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"true\", true, \"true\"},\n\t\t{\"false\", false, \"false\"},\n\t\t{\"null\", nil, \"null\"},\n\t\t{\"123\", 123, \"integer\"},\n\t\t{\"-9.7\", -9.7, \"float\"},\n\t\t{\"0xff\", 255, \"hex\"},\n\t\t{\"-2.99e-2\", -2.99e-2, \"exponential\"},\n\t\t{\"'foo'\", \"foo\", \"string\"},\n\t\t{\"'it''s foo'\", \"it's foo\", \"string\"},\n\t}\n\n\tenv := &EvaluationEnvironment{}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestOperators(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t\terror    string\n\t}{\n\t\t{\"(false || (false || true))\", true, \"logical-grouping\", \"\"},\n\t\t{\"github.action\", \"push\", \"property-dereference\", \"\"},\n\t\t{\"github['action']\", \"push\", \"property-index\", \"\"},\n\t\t{\"github.action[0]\", nil, \"string-index\", \"\"},\n\t\t{\"github.action['0']\", nil, \"string-index\", \"\"},\n\t\t{\"fromJSON('[0,1]')[1]\", 1.0, \"array-index\", \"\"},\n\t\t{\"fromJSON('[0,1]')[1.1]\", nil, \"array-index\", \"\"},\n\t\t// Disabled weird things are happening\n\t\t// {\"fromJSON('[0,1]')['1.1']\", nil, \"array-index\", \"\"},\n\t\t{\"(github.event.commits.*.author.username)[0]\", \"someone\", \"array-index-0\", \"\"},\n\t\t{\"fromJSON('[0,1]')[2]\", nil, \"array-index-out-of-bounds-0\", \"\"},\n\t\t{\"fromJSON('[0,1]')[34553]\", nil, \"array-index-out-of-bounds-1\", \"\"},\n\t\t{\"fromJSON('[0,1]')[-1]\", nil, \"array-index-out-of-bounds-2\", \"\"},\n\t\t{\"fromJSON('[0,1]')[-34553]\", nil, \"array-index-out-of-bounds-3\", \"\"},\n\t\t{\"!true\", false, \"not\", \"\"},\n\t\t{\"1 < 2\", true, \"less-than\", \"\"},\n\t\t{`'b' <= 'a'`, false, \"less-than-or-equal\", \"\"},\n\t\t{\"1 > 2\", false, \"greater-than\", \"\"},\n\t\t{`'b' >= 'a'`, true, \"greater-than-or-equal\", \"\"},\n\t\t{`'a' == 'a'`, true, \"equal\", \"\"},\n\t\t{`'a' != 'a'`, false, \"not-equal\", \"\"},\n\t\t{`true && false`, false, \"and\", \"\"},\n\t\t{`true || false`, true, \"or\", \"\"},\n\t\t{`fromJSON('{}') && true`, true, \"and-boolean-object\", \"\"},\n\t\t{`fromJSON('{}') || false`, make(map[string]interface{}), \"or-boolean-object\", \"\"},\n\t\t{\"github.event.commits[0].author.username != github.event.commits[1].author.username\", true, \"property-comparison1\", \"\"},\n\t\t{\"github.event.commits[0].author.username1 != github.event.commits[1].author.username\", true, \"property-comparison2\", \"\"},\n\t\t{\"github.event.commits[0].author.username != github.event.commits[1].author.username1\", true, \"property-comparison3\", \"\"},\n\t\t{\"github.event.commits[0].author.username1 != github.event.commits[1].author.username2\", true, \"property-comparison4\", \"\"},\n\t\t{\"secrets != env\", nil, \"property-comparison5\", \"Compare not implemented for types: left: map, right: map\"},\n\t}\n\n\tenv := &EvaluationEnvironment{\n\t\tGithub: &model.GithubContext{\n\t\t\tAction: \"push\",\n\t\t\tEvent: map[string]interface{}{\n\t\t\t\t\"commits\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"author\": map[string]interface{}{\n\t\t\t\t\t\t\t\"username\": \"someone\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"author\": map[string]interface{}{\n\t\t\t\t\t\t\t\"username\": \"someone-else\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tif tt.error != \"\" {\n\t\t\t\tassert.NotNil(t, err)\n\t\t\t\tassert.Equal(t, tt.error, err.Error())\n\t\t\t} else {\n\t\t\t\tassert.Nil(t, err)\n\t\t\t}\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestOperatorsCompare(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"!null\", true, \"not-null\"},\n\t\t{\"!-10\", false, \"not-neg-num\"},\n\t\t{\"!0\", true, \"not-zero\"},\n\t\t{\"!3.14\", false, \"not-pos-float\"},\n\t\t{\"!''\", true, \"not-empty-str\"},\n\t\t{\"!'abc'\", false, \"not-str\"},\n\t\t{\"!fromJSON('{}')\", false, \"not-obj\"},\n\t\t{\"!fromJSON('[]')\", false, \"not-arr\"},\n\t\t{`null == 0 }}`, true, \"null-coercion\"},\n\t\t{`true == 1 }}`, true, \"boolean-coercion\"},\n\t\t{`'' == 0 }}`, true, \"string-0-coercion\"},\n\t\t{`'3' == 3 }}`, true, \"string-3-coercion\"},\n\t\t{`0 == null }}`, true, \"null-coercion-alt\"},\n\t\t{`1 == true }}`, true, \"boolean-coercion-alt\"},\n\t\t{`0 == '' }}`, true, \"string-0-coercion-alt\"},\n\t\t{`3 == '3' }}`, true, \"string-3-coercion-alt\"},\n\t\t{`'TEST' == 'test' }}`, true, \"string-casing\"},\n\t\t{\"true > false }}\", true, \"bool-greater-than\"},\n\t\t{\"true >= false }}\", true, \"bool-greater-than-eq\"},\n\t\t{\"true >= true }}\", true, \"bool-greater-than-1\"},\n\t\t{\"true != false }}\", true, \"bool-not-equal\"},\n\t\t{`fromJSON('{}') < 2 }}`, false, \"object-with-less\"},\n\t\t{`fromJSON('{}') < fromJSON('[]') }}`, false, \"object/arr-with-lt\"},\n\t\t{`fromJSON('{}') > fromJSON('[]') }}`, false, \"object/arr-with-gt\"},\n\t}\n\n\tenv := &EvaluationEnvironment{\n\t\tGithub: &model.GithubContext{\n\t\t\tAction: \"push\",\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n\nfunc TestOperatorsBooleanEvaluation(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t// true &&\n\t\t{\"true && true\", true, \"true-and\"},\n\t\t{\"true && false\", false, \"true-and\"},\n\t\t{\"true && null\", nil, \"true-and\"},\n\t\t{\"true && -10\", -10, \"true-and\"},\n\t\t{\"true && 0\", 0, \"true-and\"},\n\t\t{\"true && 10\", 10, \"true-and\"},\n\t\t{\"true && 3.14\", 3.14, \"true-and\"},\n\t\t{\"true && 0.0\", 0, \"true-and\"},\n\t\t{\"true && Infinity\", math.Inf(1), \"true-and\"},\n\t\t// {\"true && -Infinity\", math.Inf(-1), \"true-and\"},\n\t\t{\"true && NaN\", math.NaN(), \"true-and\"},\n\t\t{\"true && ''\", \"\", \"true-and\"},\n\t\t{\"true && 'abc'\", \"abc\", \"true-and\"},\n\t\t// false &&\n\t\t{\"false && true\", false, \"false-and\"},\n\t\t{\"false && false\", false, \"false-and\"},\n\t\t{\"false && null\", false, \"false-and\"},\n\t\t{\"false && -10\", false, \"false-and\"},\n\t\t{\"false && 0\", false, \"false-and\"},\n\t\t{\"false && 10\", false, \"false-and\"},\n\t\t{\"false && 3.14\", false, \"false-and\"},\n\t\t{\"false && 0.0\", false, \"false-and\"},\n\t\t{\"false && Infinity\", false, \"false-and\"},\n\t\t// {\"false && -Infinity\", false, \"false-and\"},\n\t\t{\"false && NaN\", false, \"false-and\"},\n\t\t{\"false && ''\", false, \"false-and\"},\n\t\t{\"false && 'abc'\", false, \"false-and\"},\n\t\t// true ||\n\t\t{\"true || true\", true, \"true-or\"},\n\t\t{\"true || false\", true, \"true-or\"},\n\t\t{\"true || null\", true, \"true-or\"},\n\t\t{\"true || -10\", true, \"true-or\"},\n\t\t{\"true || 0\", true, \"true-or\"},\n\t\t{\"true || 10\", true, \"true-or\"},\n\t\t{\"true || 3.14\", true, \"true-or\"},\n\t\t{\"true || 0.0\", true, \"true-or\"},\n\t\t{\"true || Infinity\", true, \"true-or\"},\n\t\t// {\"true || -Infinity\", true, \"true-or\"},\n\t\t{\"true || NaN\", true, \"true-or\"},\n\t\t{\"true || ''\", true, \"true-or\"},\n\t\t{\"true || 'abc'\", true, \"true-or\"},\n\t\t// false ||\n\t\t{\"false || true\", true, \"false-or\"},\n\t\t{\"false || false\", false, \"false-or\"},\n\t\t{\"false || null\", nil, \"false-or\"},\n\t\t{\"false || -10\", -10, \"false-or\"},\n\t\t{\"false || 0\", 0, \"false-or\"},\n\t\t{\"false || 10\", 10, \"false-or\"},\n\t\t{\"false || 3.14\", 3.14, \"false-or\"},\n\t\t{\"false || 0.0\", 0, \"false-or\"},\n\t\t{\"false || Infinity\", math.Inf(1), \"false-or\"},\n\t\t// {\"false || -Infinity\", math.Inf(-1), \"false-or\"},\n\t\t{\"false || NaN\", math.NaN(), \"false-or\"},\n\t\t{\"false || ''\", \"\", \"false-or\"},\n\t\t{\"false || 'abc'\", \"abc\", \"false-or\"},\n\t\t// null &&\n\t\t{\"null && true\", nil, \"null-and\"},\n\t\t{\"null && false\", nil, \"null-and\"},\n\t\t{\"null && null\", nil, \"null-and\"},\n\t\t{\"null && -10\", nil, \"null-and\"},\n\t\t{\"null && 0\", nil, \"null-and\"},\n\t\t{\"null && 10\", nil, \"null-and\"},\n\t\t{\"null && 3.14\", nil, \"null-and\"},\n\t\t{\"null && 0.0\", nil, \"null-and\"},\n\t\t{\"null && Infinity\", nil, \"null-and\"},\n\t\t// {\"null && -Infinity\", nil, \"null-and\"},\n\t\t{\"null && NaN\", nil, \"null-and\"},\n\t\t{\"null && ''\", nil, \"null-and\"},\n\t\t{\"null && 'abc'\", nil, \"null-and\"},\n\t\t// null ||\n\t\t{\"null || true\", true, \"null-or\"},\n\t\t{\"null || false\", false, \"null-or\"},\n\t\t{\"null || null\", nil, \"null-or\"},\n\t\t{\"null || -10\", -10, \"null-or\"},\n\t\t{\"null || 0\", 0, \"null-or\"},\n\t\t{\"null || 10\", 10, \"null-or\"},\n\t\t{\"null || 3.14\", 3.14, \"null-or\"},\n\t\t{\"null || 0.0\", 0, \"null-or\"},\n\t\t{\"null || Infinity\", math.Inf(1), \"null-or\"},\n\t\t// {\"null || -Infinity\", math.Inf(-1), \"null-or\"},\n\t\t{\"null || NaN\", math.NaN(), \"null-or\"},\n\t\t{\"null || ''\", \"\", \"null-or\"},\n\t\t{\"null || 'abc'\", \"abc\", \"null-or\"},\n\t\t// -10 &&\n\t\t{\"-10 && true\", true, \"neg-num-and\"},\n\t\t{\"-10 && false\", false, \"neg-num-and\"},\n\t\t{\"-10 && null\", nil, \"neg-num-and\"},\n\t\t{\"-10 && -10\", -10, \"neg-num-and\"},\n\t\t{\"-10 && 0\", 0, \"neg-num-and\"},\n\t\t{\"-10 && 10\", 10, \"neg-num-and\"},\n\t\t{\"-10 && 3.14\", 3.14, \"neg-num-and\"},\n\t\t{\"-10 && 0.0\", 0, \"neg-num-and\"},\n\t\t{\"-10 && Infinity\", math.Inf(1), \"neg-num-and\"},\n\t\t// {\"-10 && -Infinity\", math.Inf(-1), \"neg-num-and\"},\n\t\t{\"-10 && NaN\", math.NaN(), \"neg-num-and\"},\n\t\t{\"-10 && ''\", \"\", \"neg-num-and\"},\n\t\t{\"-10 && 'abc'\", \"abc\", \"neg-num-and\"},\n\t\t// -10 ||\n\t\t{\"-10 || true\", -10, \"neg-num-or\"},\n\t\t{\"-10 || false\", -10, \"neg-num-or\"},\n\t\t{\"-10 || null\", -10, \"neg-num-or\"},\n\t\t{\"-10 || -10\", -10, \"neg-num-or\"},\n\t\t{\"-10 || 0\", -10, \"neg-num-or\"},\n\t\t{\"-10 || 10\", -10, \"neg-num-or\"},\n\t\t{\"-10 || 3.14\", -10, \"neg-num-or\"},\n\t\t{\"-10 || 0.0\", -10, \"neg-num-or\"},\n\t\t{\"-10 || Infinity\", -10, \"neg-num-or\"},\n\t\t// {\"-10 || -Infinity\", -10, \"neg-num-or\"},\n\t\t{\"-10 || NaN\", -10, \"neg-num-or\"},\n\t\t{\"-10 || ''\", -10, \"neg-num-or\"},\n\t\t{\"-10 || 'abc'\", -10, \"neg-num-or\"},\n\t\t// 0 &&\n\t\t{\"0 && true\", 0, \"zero-and\"},\n\t\t{\"0 && false\", 0, \"zero-and\"},\n\t\t{\"0 && null\", 0, \"zero-and\"},\n\t\t{\"0 && -10\", 0, \"zero-and\"},\n\t\t{\"0 && 0\", 0, \"zero-and\"},\n\t\t{\"0 && 10\", 0, \"zero-and\"},\n\t\t{\"0 && 3.14\", 0, \"zero-and\"},\n\t\t{\"0 && 0.0\", 0, \"zero-and\"},\n\t\t{\"0 && Infinity\", 0, \"zero-and\"},\n\t\t// {\"0 && -Infinity\", 0, \"zero-and\"},\n\t\t{\"0 && NaN\", 0, \"zero-and\"},\n\t\t{\"0 && ''\", 0, \"zero-and\"},\n\t\t{\"0 && 'abc'\", 0, \"zero-and\"},\n\t\t// 0 ||\n\t\t{\"0 || true\", true, \"zero-or\"},\n\t\t{\"0 || false\", false, \"zero-or\"},\n\t\t{\"0 || null\", nil, \"zero-or\"},\n\t\t{\"0 || -10\", -10, \"zero-or\"},\n\t\t{\"0 || 0\", 0, \"zero-or\"},\n\t\t{\"0 || 10\", 10, \"zero-or\"},\n\t\t{\"0 || 3.14\", 3.14, \"zero-or\"},\n\t\t{\"0 || 0.0\", 0, \"zero-or\"},\n\t\t{\"0 || Infinity\", math.Inf(1), \"zero-or\"},\n\t\t// {\"0 || -Infinity\", math.Inf(-1), \"zero-or\"},\n\t\t{\"0 || NaN\", math.NaN(), \"zero-or\"},\n\t\t{\"0 || ''\", \"\", \"zero-or\"},\n\t\t{\"0 || 'abc'\", \"abc\", \"zero-or\"},\n\t\t// 10 &&\n\t\t{\"10 && true\", true, \"pos-num-and\"},\n\t\t{\"10 && false\", false, \"pos-num-and\"},\n\t\t{\"10 && null\", nil, \"pos-num-and\"},\n\t\t{\"10 && -10\", -10, \"pos-num-and\"},\n\t\t{\"10 && 0\", 0, \"pos-num-and\"},\n\t\t{\"10 && 10\", 10, \"pos-num-and\"},\n\t\t{\"10 && 3.14\", 3.14, \"pos-num-and\"},\n\t\t{\"10 && 0.0\", 0, \"pos-num-and\"},\n\t\t{\"10 && Infinity\", math.Inf(1), \"pos-num-and\"},\n\t\t// {\"10 && -Infinity\", math.Inf(-1), \"pos-num-and\"},\n\t\t{\"10 && NaN\", math.NaN(), \"pos-num-and\"},\n\t\t{\"10 && ''\", \"\", \"pos-num-and\"},\n\t\t{\"10 && 'abc'\", \"abc\", \"pos-num-and\"},\n\t\t// 10 ||\n\t\t{\"10 || true\", 10, \"pos-num-or\"},\n\t\t{\"10 || false\", 10, \"pos-num-or\"},\n\t\t{\"10 || null\", 10, \"pos-num-or\"},\n\t\t{\"10 || -10\", 10, \"pos-num-or\"},\n\t\t{\"10 || 0\", 10, \"pos-num-or\"},\n\t\t{\"10 || 10\", 10, \"pos-num-or\"},\n\t\t{\"10 || 3.14\", 10, \"pos-num-or\"},\n\t\t{\"10 || 0.0\", 10, \"pos-num-or\"},\n\t\t{\"10 || Infinity\", 10, \"pos-num-or\"},\n\t\t// {\"10 || -Infinity\", 10, \"pos-num-or\"},\n\t\t{\"10 || NaN\", 10, \"pos-num-or\"},\n\t\t{\"10 || ''\", 10, \"pos-num-or\"},\n\t\t{\"10 || 'abc'\", 10, \"pos-num-or\"},\n\t\t// 3.14 &&\n\t\t{\"3.14 && true\", true, \"pos-float-and\"},\n\t\t{\"3.14 && false\", false, \"pos-float-and\"},\n\t\t{\"3.14 && null\", nil, \"pos-float-and\"},\n\t\t{\"3.14 && -10\", -10, \"pos-float-and\"},\n\t\t{\"3.14 && 0\", 0, \"pos-float-and\"},\n\t\t{\"3.14 && 10\", 10, \"pos-float-and\"},\n\t\t{\"3.14 && 3.14\", 3.14, \"pos-float-and\"},\n\t\t{\"3.14 && 0.0\", 0, \"pos-float-and\"},\n\t\t{\"3.14 && Infinity\", math.Inf(1), \"pos-float-and\"},\n\t\t// {\"3.14 && -Infinity\", math.Inf(-1), \"pos-float-and\"},\n\t\t{\"3.14 && NaN\", math.NaN(), \"pos-float-and\"},\n\t\t{\"3.14 && ''\", \"\", \"pos-float-and\"},\n\t\t{\"3.14 && 'abc'\", \"abc\", \"pos-float-and\"},\n\t\t// 3.14 ||\n\t\t{\"3.14 || true\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || false\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || null\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || -10\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || 0\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || 10\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || 3.14\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || 0.0\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || Infinity\", 3.14, \"pos-float-or\"},\n\t\t// {\"3.14 || -Infinity\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || NaN\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || ''\", 3.14, \"pos-float-or\"},\n\t\t{\"3.14 || 'abc'\", 3.14, \"pos-float-or\"},\n\t\t// Infinity &&\n\t\t{\"Infinity && true\", true, \"pos-inf-and\"},\n\t\t{\"Infinity && false\", false, \"pos-inf-and\"},\n\t\t{\"Infinity && null\", nil, \"pos-inf-and\"},\n\t\t{\"Infinity && -10\", -10, \"pos-inf-and\"},\n\t\t{\"Infinity && 0\", 0, \"pos-inf-and\"},\n\t\t{\"Infinity && 10\", 10, \"pos-inf-and\"},\n\t\t{\"Infinity && 3.14\", 3.14, \"pos-inf-and\"},\n\t\t{\"Infinity && 0.0\", 0, \"pos-inf-and\"},\n\t\t{\"Infinity && Infinity\", math.Inf(1), \"pos-inf-and\"},\n\t\t// {\"Infinity && -Infinity\", math.Inf(-1), \"pos-inf-and\"},\n\t\t{\"Infinity && NaN\", math.NaN(), \"pos-inf-and\"},\n\t\t{\"Infinity && ''\", \"\", \"pos-inf-and\"},\n\t\t{\"Infinity && 'abc'\", \"abc\", \"pos-inf-and\"},\n\t\t// Infinity ||\n\t\t{\"Infinity || true\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || false\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || null\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || -10\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || 0\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || 10\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || 3.14\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || 0.0\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || Infinity\", math.Inf(1), \"pos-inf-or\"},\n\t\t// {\"Infinity || -Infinity\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || NaN\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || ''\", math.Inf(1), \"pos-inf-or\"},\n\t\t{\"Infinity || 'abc'\", math.Inf(1), \"pos-inf-or\"},\n\t\t// -Infinity &&\n\t\t// {\"-Infinity && true\", true, \"neg-inf-and\"},\n\t\t// {\"-Infinity && false\", false, \"neg-inf-and\"},\n\t\t// {\"-Infinity && null\", nil, \"neg-inf-and\"},\n\t\t// {\"-Infinity && -10\", -10, \"neg-inf-and\"},\n\t\t// {\"-Infinity && 0\", 0, \"neg-inf-and\"},\n\t\t// {\"-Infinity && 10\", 10, \"neg-inf-and\"},\n\t\t// {\"-Infinity && 3.14\", 3.14, \"neg-inf-and\"},\n\t\t// {\"-Infinity && 0.0\", 0, \"neg-inf-and\"},\n\t\t// {\"-Infinity && Infinity\", math.Inf(1), \"neg-inf-and\"},\n\t\t// {\"-Infinity && -Infinity\", math.Inf(-1), \"neg-inf-and\"},\n\t\t// {\"-Infinity && NaN\", math.NaN(), \"neg-inf-and\"},\n\t\t// {\"-Infinity && ''\", \"\", \"neg-inf-and\"},\n\t\t// {\"-Infinity && 'abc'\", \"abc\", \"neg-inf-and\"},\n\t\t// -Infinity ||\n\t\t// {\"-Infinity || true\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || false\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || null\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || -10\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || 0\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || 10\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || 3.14\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || 0.0\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || Infinity\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || -Infinity\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || NaN\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || ''\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// {\"-Infinity || 'abc'\", math.Inf(-1), \"neg-inf-or\"},\n\t\t// NaN &&\n\t\t{\"NaN && true\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && false\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && null\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && -10\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && 0\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && 10\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && 3.14\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && 0.0\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && Infinity\", math.NaN(), \"nan-and\"},\n\t\t// {\"NaN && -Infinity\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && NaN\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && ''\", math.NaN(), \"nan-and\"},\n\t\t{\"NaN && 'abc'\", math.NaN(), \"nan-and\"},\n\t\t// NaN ||\n\t\t{\"NaN || true\", true, \"nan-or\"},\n\t\t{\"NaN || false\", false, \"nan-or\"},\n\t\t{\"NaN || null\", nil, \"nan-or\"},\n\t\t{\"NaN || -10\", -10, \"nan-or\"},\n\t\t{\"NaN || 0\", 0, \"nan-or\"},\n\t\t{\"NaN || 10\", 10, \"nan-or\"},\n\t\t{\"NaN || 3.14\", 3.14, \"nan-or\"},\n\t\t{\"NaN || 0.0\", 0, \"nan-or\"},\n\t\t{\"NaN || Infinity\", math.Inf(1), \"nan-or\"},\n\t\t// {\"NaN || -Infinity\", math.Inf(-1), \"nan-or\"},\n\t\t{\"NaN || NaN\", math.NaN(), \"nan-or\"},\n\t\t{\"NaN || ''\", \"\", \"nan-or\"},\n\t\t{\"NaN || 'abc'\", \"abc\", \"nan-or\"},\n\t\t// \"\" &&\n\t\t{\"'' && true\", \"\", \"empty-str-and\"},\n\t\t{\"'' && false\", \"\", \"empty-str-and\"},\n\t\t{\"'' && null\", \"\", \"empty-str-and\"},\n\t\t{\"'' && -10\", \"\", \"empty-str-and\"},\n\t\t{\"'' && 0\", \"\", \"empty-str-and\"},\n\t\t{\"'' && 10\", \"\", \"empty-str-and\"},\n\t\t{\"'' && 3.14\", \"\", \"empty-str-and\"},\n\t\t{\"'' && 0.0\", \"\", \"empty-str-and\"},\n\t\t{\"'' && Infinity\", \"\", \"empty-str-and\"},\n\t\t// {\"'' && -Infinity\", \"\", \"empty-str-and\"},\n\t\t{\"'' && NaN\", \"\", \"empty-str-and\"},\n\t\t{\"'' && ''\", \"\", \"empty-str-and\"},\n\t\t{\"'' && 'abc'\", \"\", \"empty-str-and\"},\n\t\t// \"\" ||\n\t\t{\"'' || true\", true, \"empty-str-or\"},\n\t\t{\"'' || false\", false, \"empty-str-or\"},\n\t\t{\"'' || null\", nil, \"empty-str-or\"},\n\t\t{\"'' || -10\", -10, \"empty-str-or\"},\n\t\t{\"'' || 0\", 0, \"empty-str-or\"},\n\t\t{\"'' || 10\", 10, \"empty-str-or\"},\n\t\t{\"'' || 3.14\", 3.14, \"empty-str-or\"},\n\t\t{\"'' || 0.0\", 0, \"empty-str-or\"},\n\t\t{\"'' || Infinity\", math.Inf(1), \"empty-str-or\"},\n\t\t// {\"'' || -Infinity\", math.Inf(-1), \"empty-str-or\"},\n\t\t{\"'' || NaN\", math.NaN(), \"empty-str-or\"},\n\t\t{\"'' || ''\", \"\", \"empty-str-or\"},\n\t\t{\"'' || 'abc'\", \"abc\", \"empty-str-or\"},\n\t\t// \"abc\" &&\n\t\t{\"'abc' && true\", true, \"str-and\"},\n\t\t{\"'abc' && false\", false, \"str-and\"},\n\t\t{\"'abc' && null\", nil, \"str-and\"},\n\t\t{\"'abc' && -10\", -10, \"str-and\"},\n\t\t{\"'abc' && 0\", 0, \"str-and\"},\n\t\t{\"'abc' && 10\", 10, \"str-and\"},\n\t\t{\"'abc' && 3.14\", 3.14, \"str-and\"},\n\t\t{\"'abc' && 0.0\", 0, \"str-and\"},\n\t\t{\"'abc' && Infinity\", math.Inf(1), \"str-and\"},\n\t\t// {\"'abc' && -Infinity\", math.Inf(-1), \"str-and\"},\n\t\t{\"'abc' && NaN\", math.NaN(), \"str-and\"},\n\t\t{\"'abc' && ''\", \"\", \"str-and\"},\n\t\t{\"'abc' && 'abc'\", \"abc\", \"str-and\"},\n\t\t// \"abc\" ||\n\t\t{\"'abc' || true\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || false\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || null\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || -10\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || 0\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || 10\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || 3.14\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || 0.0\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || Infinity\", \"abc\", \"str-or\"},\n\t\t// {\"'abc' || -Infinity\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || NaN\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || ''\", \"abc\", \"str-or\"},\n\t\t{\"'abc' || 'abc'\", \"abc\", \"str-or\"},\n\t\t// extra tests\n\t\t{\"0.0 && true\", 0, \"float-evaluation-0-alt\"},\n\t\t{\"-1.5 && true\", true, \"float-evaluation-neg-alt\"},\n\t}\n\n\tenv := &EvaluationEnvironment{\n\t\tGithub: &model.GithubContext{\n\t\t\tAction: \"push\",\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tif expected, ok := tt.expected.(float64); ok && math.IsNaN(expected) {\n\t\t\t\tassert.True(t, math.IsNaN(output.(float64)))\n\t\t\t} else {\n\t\t\t\tassert.Equal(t, tt.expected, output)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestContexts(t *testing.T) {\n\ttable := []struct {\n\t\tinput    string\n\t\texpected interface{}\n\t\tname     string\n\t}{\n\t\t{\"github.action\", \"push\", \"github-context\"},\n\t\t{\"github.event.commits[0].message\", nil, \"github-context-noexist-prop\"},\n\t\t{\"fromjson('{\\\"commits\\\":[]}').commits[0].message\", nil, \"github-context-noexist-prop\"},\n\t\t{\"github.event.pull_request.labels.*.name\", nil, \"github-context-noexist-prop\"},\n\t\t{\"env.TEST\", \"value\", \"env-context\"},\n\t\t{\"job.status\", \"success\", \"job-context\"},\n\t\t{\"steps.step-id.outputs.name\", \"value\", \"steps-context\"},\n\t\t{\"steps.step-id.conclusion\", \"success\", \"steps-context-conclusion\"},\n\t\t{\"steps.step-id.conclusion && true\", true, \"steps-context-conclusion\"},\n\t\t{\"steps.step-id2.conclusion\", \"skipped\", \"steps-context-conclusion\"},\n\t\t{\"steps.step-id2.conclusion && true\", true, \"steps-context-conclusion\"},\n\t\t{\"steps.step-id.outcome\", \"success\", \"steps-context-outcome\"},\n\t\t{\"steps.step-id['outcome']\", \"success\", \"steps-context-outcome\"},\n\t\t{\"steps.step-id.outcome == 'success'\", true, \"steps-context-outcome\"},\n\t\t{\"steps.step-id['outcome'] == 'success'\", true, \"steps-context-outcome\"},\n\t\t{\"steps.step-id.outcome && true\", true, \"steps-context-outcome\"},\n\t\t{\"steps['step-id']['outcome'] && true\", true, \"steps-context-outcome\"},\n\t\t{\"steps.step-id2.outcome\", \"failure\", \"steps-context-outcome\"},\n\t\t{\"steps.step-id2.outcome && true\", true, \"steps-context-outcome\"},\n\t\t// Disabled, since the interpreter is still too broken\n\t\t// {\"contains(steps.*.outcome, 'success')\", true, \"steps-context-array-outcome\"},\n\t\t// {\"contains(steps.*.outcome, 'failure')\", true, \"steps-context-array-outcome\"},\n\t\t// {\"contains(steps.*.outputs.name, 'value')\", true, \"steps-context-array-outputs\"},\n\t\t{\"runner.os\", \"Linux\", \"runner-context\"},\n\t\t{\"secrets.name\", \"value\", \"secrets-context\"},\n\t\t{\"vars.name\", \"value\", \"vars-context\"},\n\t\t{\"strategy.fail-fast\", true, \"strategy-context\"},\n\t\t{\"matrix.os\", \"Linux\", \"matrix-context\"},\n\t\t{\"needs.job-id.outputs.output-name\", \"value\", \"needs-context\"},\n\t\t{\"needs.job-id.result\", \"success\", \"needs-context\"},\n\t\t{\"contains(needs.*.result, 'success')\", true, \"needs-wildcard-context-contains-success\"},\n\t\t{\"contains(needs.*.result, 'failure')\", false, \"needs-wildcard-context-contains-failure\"},\n\t\t{\"inputs.name\", \"value\", \"inputs-context\"},\n\t}\n\n\tenv := &EvaluationEnvironment{\n\t\tGithub: &model.GithubContext{\n\t\t\tAction: \"push\",\n\t\t},\n\t\tEnv: map[string]string{\n\t\t\t\"TEST\": \"value\",\n\t\t},\n\t\tJob: &model.JobContext{\n\t\t\tStatus: \"success\",\n\t\t},\n\t\tSteps: map[string]*model.StepResult{\n\t\t\t\"step-id\": {\n\t\t\t\tOutputs: map[string]string{\n\t\t\t\t\t\"name\": \"value\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"step-id2\": {\n\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\tConclusion: model.StepStatusSkipped,\n\t\t\t},\n\t\t},\n\t\tRunner: map[string]interface{}{\n\t\t\t\"os\":         \"Linux\",\n\t\t\t\"temp\":       \"/tmp\",\n\t\t\t\"tool_cache\": \"/opt/hostedtoolcache\",\n\t\t},\n\t\tSecrets: map[string]string{\n\t\t\t\"name\": \"value\",\n\t\t},\n\t\tVars: map[string]string{\n\t\t\t\"name\": \"value\",\n\t\t},\n\t\tStrategy: map[string]interface{}{\n\t\t\t\"fail-fast\": true,\n\t\t},\n\t\tMatrix: map[string]interface{}{\n\t\t\t\"os\": \"Linux\",\n\t\t},\n\t\tNeeds: map[string]Needs{\n\t\t\t\"job-id\": {\n\t\t\t\tOutputs: map[string]string{\n\t\t\t\t\t\"output-name\": \"value\",\n\t\t\t\t},\n\t\t\t\tResult: \"success\",\n\t\t\t},\n\t\t\t\"another-job-id\": {\n\t\t\t\tOutputs: map[string]string{\n\t\t\t\t\t\"output-name\": \"value\",\n\t\t\t\t},\n\t\t\t\tResult: \"success\",\n\t\t\t},\n\t\t},\n\t\tInputs: map[string]interface{}{\n\t\t\t\"name\": \"value\",\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\toutput, err := NewInterpeter(env, Config{}).Evaluate(tt.input, DefaultStatusCheckNone)\n\t\t\tassert.Nil(t, err)\n\n\t\t\tassert.Equal(t, tt.expected, output)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/exprparser/testdata/for-hashing-1.txt",
    "content": "Hello\n"
  },
  {
    "path": "pkg/exprparser/testdata/for-hashing-2.txt",
    "content": "World!\n"
  },
  {
    "path": "pkg/exprparser/testdata/for-hashing-3/data.txt",
    "content": "Knock knock!\n"
  },
  {
    "path": "pkg/exprparser/testdata/for-hashing-3/nested/nested-data.txt",
    "content": "Anybody home?\n"
  },
  {
    "path": "pkg/filecollector/file_collector.go",
    "content": "package filecollector\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tgit \"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plumbing/filemode\"\n\t\"github.com/go-git/go-git/v5/plumbing/format/gitignore\"\n\t\"github.com/go-git/go-git/v5/plumbing/format/index\"\n)\n\ntype Handler interface {\n\tWriteFile(path string, fi fs.FileInfo, linkName string, f io.Reader) error\n}\n\ntype TarCollector struct {\n\tTarWriter *tar.Writer\n\tUID       int\n\tGID       int\n\tDstDir    string\n}\n\nfunc (tc TarCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string, f io.Reader) error {\n\t// create a new dir/file header\n\theader, err := tar.FileInfoHeader(fi, linkName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// update the name to correctly reflect the desired destination when untaring\n\theader.Name = path.Join(tc.DstDir, fpath)\n\theader.Mode = int64(fi.Mode())\n\theader.ModTime = fi.ModTime()\n\theader.Uid = tc.UID\n\theader.Gid = tc.GID\n\n\t// write the header\n\tif err := tc.TarWriter.WriteHeader(header); err != nil {\n\t\treturn err\n\t}\n\n\t// this is a symlink no reader provided\n\tif f == nil {\n\t\treturn nil\n\t}\n\n\t// copy file data into tar writer\n\tif _, err := io.Copy(tc.TarWriter, f); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\ntype CopyCollector struct {\n\tDstDir string\n}\n\nfunc (cc *CopyCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string, f io.Reader) error {\n\tfdestpath := filepath.Join(cc.DstDir, fpath)\n\tif err := os.MkdirAll(filepath.Dir(fdestpath), 0o777); err != nil {\n\t\treturn err\n\t}\n\tif linkName != \"\" {\n\t\treturn os.Symlink(linkName, fdestpath)\n\t}\n\tdf, err := os.OpenFile(fdestpath, os.O_CREATE|os.O_WRONLY, fi.Mode())\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer df.Close()\n\tif _, err := io.Copy(df, f); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\ntype FileCollector struct {\n\tIgnorer   gitignore.Matcher\n\tSrcPath   string\n\tSrcPrefix string\n\tFs        Fs\n\tHandler   Handler\n}\n\ntype Fs interface {\n\tWalk(root string, fn filepath.WalkFunc) error\n\tOpenGitIndex(path string) (*index.Index, error)\n\tOpen(path string) (io.ReadCloser, error)\n\tReadlink(path string) (string, error)\n}\n\ntype DefaultFs struct {\n}\n\nfunc (*DefaultFs) Walk(root string, fn filepath.WalkFunc) error {\n\treturn filepath.Walk(root, fn)\n}\n\nfunc (*DefaultFs) OpenGitIndex(path string) (*index.Index, error) {\n\tr, err := git.PlainOpen(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti, err := r.Storer.Index()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn i, nil\n}\n\nfunc (*DefaultFs) Open(path string) (io.ReadCloser, error) {\n\treturn os.Open(path)\n}\n\nfunc (*DefaultFs) Readlink(path string) (string, error) {\n\treturn os.Readlink(path)\n}\n\n//nolint:gocyclo\nfunc (fc *FileCollector) CollectFiles(ctx context.Context, submodulePath []string) filepath.WalkFunc {\n\ti, _ := fc.Fs.OpenGitIndex(path.Join(fc.SrcPath, path.Join(submodulePath...)))\n\treturn func(file string, fi os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif ctx != nil {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn fmt.Errorf(\"copy cancelled\")\n\t\t\tdefault:\n\t\t\t}\n\t\t}\n\n\t\tsansPrefix := strings.TrimPrefix(file, fc.SrcPrefix)\n\t\tsplit := strings.Split(sansPrefix, string(filepath.Separator))\n\t\t// The root folders should be skipped, submodules only have the last path component set to \".\" by filepath.Walk\n\t\tif fi.IsDir() && len(split) > 0 && split[len(split)-1] == \".\" {\n\t\t\treturn nil\n\t\t}\n\t\tvar entry *index.Entry\n\t\tif i != nil {\n\t\t\tentry, err = i.Entry(strings.Join(split[len(submodulePath):], \"/\"))\n\t\t} else {\n\t\t\terr = index.ErrEntryNotFound\n\t\t}\n\t\tif err != nil && fc.Ignorer != nil && fc.Ignorer.Match(split, fi.IsDir()) {\n\t\t\tif fi.IsDir() {\n\t\t\t\tif i != nil {\n\t\t\t\t\tms, err := i.Glob(strings.Join(append(split[len(submodulePath):], \"**\"), \"/\"))\n\t\t\t\t\tif err != nil || len(ms) == 0 {\n\t\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tif err == nil && entry.Mode == filemode.Submodule {\n\t\t\terr = fc.Fs.Walk(file, fc.CollectFiles(ctx, split))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn filepath.SkipDir\n\t\t}\n\t\tpath := filepath.ToSlash(sansPrefix)\n\n\t\t// return on non-regular files (thanks to [kumo](https://medium.com/@komuw/just-like-you-did-fbdd7df829d3) for this suggested update)\n\t\tif fi.Mode()&os.ModeSymlink == os.ModeSymlink {\n\t\t\tlinkName, err := fc.Fs.Readlink(file)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to readlink '%s': %w\", file, err)\n\t\t\t}\n\t\t\treturn fc.Handler.WriteFile(path, fi, linkName, nil)\n\t\t} else if !fi.Mode().IsRegular() {\n\t\t\treturn nil\n\t\t}\n\n\t\t// open file\n\t\tf, err := fc.Fs.Open(file)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer f.Close()\n\n\t\tif ctx != nil {\n\t\t\t// make io.Copy cancellable by closing the file\n\t\t\tcpctx, cpfinish := context.WithCancel(ctx)\n\t\t\tdefer cpfinish()\n\t\t\tgo func() {\n\t\t\t\tselect {\n\t\t\t\tcase <-cpctx.Done():\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\t\tf.Close()\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\n\t\treturn fc.Handler.WriteFile(path, fi, \"\", f)\n\t}\n}\n"
  },
  {
    "path": "pkg/filecollector/file_collector_test.go",
    "content": "package filecollector\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"io\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/go-git/go-billy/v5\"\n\t\"github.com/go-git/go-billy/v5/memfs\"\n\tgit \"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plumbing/cache\"\n\t\"github.com/go-git/go-git/v5/plumbing/format/gitignore\"\n\t\"github.com/go-git/go-git/v5/plumbing/format/index\"\n\t\"github.com/go-git/go-git/v5/storage/filesystem\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\ntype memoryFs struct {\n\tbilly.Filesystem\n}\n\nfunc (mfs *memoryFs) walk(root string, fn filepath.WalkFunc) error {\n\tdir, err := mfs.ReadDir(root)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor i := 0; i < len(dir); i++ {\n\t\tfilename := filepath.Join(root, dir[i].Name())\n\t\terr = fn(filename, dir[i], nil)\n\t\tif dir[i].IsDir() {\n\t\t\tif err == filepath.SkipDir {\n\t\t\t\terr = nil\n\t\t\t} else if err := mfs.walk(filename, fn); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (mfs *memoryFs) Walk(root string, fn filepath.WalkFunc) error {\n\tstat, err := mfs.Lstat(root)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = fn(strings.Join([]string{root, \".\"}, string(filepath.Separator)), stat, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn mfs.walk(root, fn)\n}\n\nfunc (mfs *memoryFs) OpenGitIndex(path string) (*index.Index, error) {\n\tf, _ := mfs.Filesystem.Chroot(filepath.Join(path, \".git\"))\n\tstorage := filesystem.NewStorage(f, cache.NewObjectLRUDefault())\n\ti, err := storage.Index()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn i, nil\n}\n\nfunc (mfs *memoryFs) Open(path string) (io.ReadCloser, error) {\n\treturn mfs.Filesystem.Open(path)\n}\n\nfunc (mfs *memoryFs) Readlink(path string) (string, error) {\n\treturn mfs.Filesystem.Readlink(path)\n}\n\nfunc TestIgnoredTrackedfile(t *testing.T) {\n\tfs := memfs.New()\n\t_ = fs.MkdirAll(\"mygitrepo/.git\", 0o777)\n\tdotgit, _ := fs.Chroot(\"mygitrepo/.git\")\n\tworktree, _ := fs.Chroot(\"mygitrepo\")\n\trepo, _ := git.Init(filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault()), worktree)\n\tf, _ := worktree.Create(\".gitignore\")\n\t_, _ = f.Write([]byte(\".*\\n\"))\n\tf.Close()\n\t// This file shouldn't be in the tar\n\tf, _ = worktree.Create(\".env\")\n\t_, _ = f.Write([]byte(\"test=val1\\n\"))\n\tf.Close()\n\tw, _ := repo.Worktree()\n\t// .gitignore is in the tar after adding it to the index\n\t_, _ = w.Add(\".gitignore\")\n\n\ttmpTar, _ := fs.Create(\"temp.tar\")\n\ttw := tar.NewWriter(tmpTar)\n\tps, _ := gitignore.ReadPatterns(worktree, []string{})\n\tignorer := gitignore.NewMatcher(ps)\n\tfc := &FileCollector{\n\t\tFs:        &memoryFs{Filesystem: fs},\n\t\tIgnorer:   ignorer,\n\t\tSrcPath:   \"mygitrepo\",\n\t\tSrcPrefix: \"mygitrepo\" + string(filepath.Separator),\n\t\tHandler: &TarCollector{\n\t\t\tTarWriter: tw,\n\t\t},\n\t}\n\terr := fc.Fs.Walk(\"mygitrepo\", fc.CollectFiles(context.Background(), []string{}))\n\tassert.NoError(t, err, \"successfully collect files\")\n\ttw.Close()\n\t_, _ = tmpTar.Seek(0, io.SeekStart)\n\ttr := tar.NewReader(tmpTar)\n\th, err := tr.Next()\n\tassert.NoError(t, err, \"tar must not be empty\")\n\tassert.Equal(t, \".gitignore\", h.Name)\n\t_, err = tr.Next()\n\tassert.ErrorIs(t, err, io.EOF, \"tar must only contain one element\")\n}\n\nfunc TestSymlinks(t *testing.T) {\n\tfs := memfs.New()\n\t_ = fs.MkdirAll(\"mygitrepo/.git\", 0o777)\n\tdotgit, _ := fs.Chroot(\"mygitrepo/.git\")\n\tworktree, _ := fs.Chroot(\"mygitrepo\")\n\trepo, _ := git.Init(filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault()), worktree)\n\t// This file shouldn't be in the tar\n\tf, err := worktree.Create(\".env\")\n\tassert.NoError(t, err)\n\t_, err = f.Write([]byte(\"test=val1\\n\"))\n\tassert.NoError(t, err)\n\tf.Close()\n\terr = worktree.Symlink(\".env\", \"test.env\")\n\tassert.NoError(t, err)\n\n\tw, err := repo.Worktree()\n\tassert.NoError(t, err)\n\n\t// .gitignore is in the tar after adding it to the index\n\t_, err = w.Add(\".env\")\n\tassert.NoError(t, err)\n\t_, err = w.Add(\"test.env\")\n\tassert.NoError(t, err)\n\n\ttmpTar, _ := fs.Create(\"temp.tar\")\n\ttw := tar.NewWriter(tmpTar)\n\tps, _ := gitignore.ReadPatterns(worktree, []string{})\n\tignorer := gitignore.NewMatcher(ps)\n\tfc := &FileCollector{\n\t\tFs:        &memoryFs{Filesystem: fs},\n\t\tIgnorer:   ignorer,\n\t\tSrcPath:   \"mygitrepo\",\n\t\tSrcPrefix: \"mygitrepo\" + string(filepath.Separator),\n\t\tHandler: &TarCollector{\n\t\t\tTarWriter: tw,\n\t\t},\n\t}\n\terr = fc.Fs.Walk(\"mygitrepo\", fc.CollectFiles(context.Background(), []string{}))\n\tassert.NoError(t, err, \"successfully collect files\")\n\ttw.Close()\n\t_, _ = tmpTar.Seek(0, io.SeekStart)\n\ttr := tar.NewReader(tmpTar)\n\th, err := tr.Next()\n\tfiles := map[string]tar.Header{}\n\tfor err == nil {\n\t\tfiles[h.Name] = *h\n\t\th, err = tr.Next()\n\t}\n\n\tassert.Equal(t, \".env\", files[\".env\"].Name)\n\tassert.Equal(t, \"test.env\", files[\"test.env\"].Name)\n\tassert.Equal(t, \".env\", files[\"test.env\"].Linkname)\n\tassert.ErrorIs(t, err, io.EOF, \"tar must be read cleanly to EOF\")\n}\n"
  },
  {
    "path": "pkg/gh/gh.go",
    "content": "package gh\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"os/exec\"\n)\n\nfunc GetToken(ctx context.Context, workingDirectory string) (string, error) {\n\tvar token string\n\n\t// Locate the 'gh' executable\n\tpath, err := exec.LookPath(\"gh\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Command setup\n\tcmd := exec.CommandContext(ctx, path, \"auth\", \"token\")\n\tcmd.Dir = workingDirectory\n\n\t// Capture the output\n\tvar out bytes.Buffer\n\tcmd.Stdout = &out\n\n\t// Run the command\n\terr = cmd.Run()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Read the first line of the output\n\tscanner := bufio.NewScanner(&out)\n\tif scanner.Scan() {\n\t\ttoken = scanner.Text()\n\t}\n\n\treturn token, nil\n}\n"
  },
  {
    "path": "pkg/gh/gh_test.go",
    "content": "package gh\n\nimport (\n\t\"context\"\n\t\"testing\"\n)\n\nfunc TestGetToken(t *testing.T) {\n\ttoken, _ := GetToken(context.TODO(), \"\")\n\tt.Log(token)\n}\n"
  },
  {
    "path": "pkg/lookpath/LICENSE",
    "content": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t* Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t* Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t* Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "pkg/lookpath/env.go",
    "content": "package lookpath\n\nimport \"os\"\n\ntype Env interface {\n\tGetenv(name string) string\n}\n\ntype defaultEnv struct {\n}\n\nfunc (*defaultEnv) Getenv(name string) string {\n\treturn os.Getenv(name)\n}\n\nfunc LookPath(file string) (string, error) {\n\treturn LookPath2(file, &defaultEnv{})\n}\n"
  },
  {
    "path": "pkg/lookpath/error.go",
    "content": "package lookpath\n\ntype Error struct {\n\tName string\n\tErr  error\n}\n\nfunc (e *Error) Error() string {\n\treturn e.Err.Error()\n}\n"
  },
  {
    "path": "pkg/lookpath/lp_js.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n//go:build js && wasm\n\npackage lookpath\n\nimport (\n\t\"errors\"\n)\n\n// ErrNotFound is the error resulting if a path search failed to find an executable file.\nvar ErrNotFound = errors.New(\"executable file not found in $PATH\")\n\n// LookPath searches for an executable named file in the\n// directories named by the PATH environment variable.\n// If file contains a slash, it is tried directly and the PATH is not consulted.\n// The result may be an absolute path or a path relative to the current directory.\nfunc LookPath2(file string, lenv Env) (string, error) {\n\t// Wasm can not execute processes, so act as if there are no executables at all.\n\treturn \"\", &Error{file, ErrNotFound}\n}\n"
  },
  {
    "path": "pkg/lookpath/lp_plan9.go",
    "content": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage lookpath\n\nimport (\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// ErrNotFound is the error resulting if a path search failed to find an executable file.\nvar ErrNotFound = errors.New(\"executable file not found in $path\")\n\nfunc findExecutable(file string) error {\n\td, err := os.Stat(file)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif m := d.Mode(); !m.IsDir() && m&0111 != 0 {\n\t\treturn nil\n\t}\n\treturn fs.ErrPermission\n}\n\n// LookPath searches for an executable named file in the\n// directories named by the path environment variable.\n// If file begins with \"/\", \"#\", \"./\", or \"../\", it is tried\n// directly and the path is not consulted.\n// The result may be an absolute path or a path relative to the current directory.\nfunc LookPath2(file string, lenv Env) (string, error) {\n\t// skip the path lookup for these prefixes\n\tskip := []string{\"/\", \"#\", \"./\", \"../\"}\n\n\tfor _, p := range skip {\n\t\tif strings.HasPrefix(file, p) {\n\t\t\terr := findExecutable(file)\n\t\t\tif err == nil {\n\t\t\t\treturn file, nil\n\t\t\t}\n\t\t\treturn \"\", &Error{file, err}\n\t\t}\n\t}\n\n\tpath := lenv.Getenv(\"path\")\n\tfor _, dir := range filepath.SplitList(path) {\n\t\tpath := filepath.Join(dir, file)\n\t\tif err := findExecutable(path); err == nil {\n\t\t\treturn path, nil\n\t\t}\n\t}\n\treturn \"\", &Error{file, ErrNotFound}\n}\n"
  },
  {
    "path": "pkg/lookpath/lp_unix.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris\n\npackage lookpath\n\nimport (\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// ErrNotFound is the error resulting if a path search failed to find an executable file.\nvar ErrNotFound = errors.New(\"executable file not found in $PATH\")\n\nfunc findExecutable(file string) error {\n\td, err := os.Stat(file)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif m := d.Mode(); !m.IsDir() && m&0111 != 0 {\n\t\treturn nil\n\t}\n\treturn fs.ErrPermission\n}\n\n// LookPath searches for an executable named file in the\n// directories named by the PATH environment variable.\n// If file contains a slash, it is tried directly and the PATH is not consulted.\n// The result may be an absolute path or a path relative to the current directory.\nfunc LookPath2(file string, lenv Env) (string, error) {\n\t// NOTE(rsc): I wish we could use the Plan 9 behavior here\n\t// (only bypass the path if file begins with / or ./ or ../)\n\t// but that would not match all the Unix shells.\n\n\tif strings.Contains(file, \"/\") {\n\t\terr := findExecutable(file)\n\t\tif err == nil {\n\t\t\treturn file, nil\n\t\t}\n\t\treturn \"\", &Error{file, err}\n\t}\n\tpath := lenv.Getenv(\"PATH\")\n\tfor _, dir := range filepath.SplitList(path) {\n\t\tif dir == \"\" {\n\t\t\t// Unix shell semantics: path element \"\" means \".\"\n\t\t\tdir = \".\"\n\t\t}\n\t\tpath := filepath.Join(dir, file)\n\t\tif err := findExecutable(path); err == nil {\n\t\t\treturn path, nil\n\t\t}\n\t}\n\treturn \"\", &Error{file, ErrNotFound}\n}\n"
  },
  {
    "path": "pkg/lookpath/lp_windows.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage lookpath\n\nimport (\n\t\"errors\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// ErrNotFound is the error resulting if a path search failed to find an executable file.\nvar ErrNotFound = errors.New(\"executable file not found in %PATH%\")\n\nfunc chkStat(file string) error {\n\td, err := os.Stat(file)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif d.IsDir() {\n\t\treturn fs.ErrPermission\n\t}\n\treturn nil\n}\n\nfunc hasExt(file string) bool {\n\ti := strings.LastIndex(file, \".\")\n\tif i < 0 {\n\t\treturn false\n\t}\n\treturn strings.LastIndexAny(file, `:\\/`) < i\n}\n\nfunc findExecutable(file string, exts []string) (string, error) {\n\tif len(exts) == 0 {\n\t\treturn file, chkStat(file)\n\t}\n\tif hasExt(file) {\n\t\tif chkStat(file) == nil {\n\t\t\treturn file, nil\n\t\t}\n\t}\n\tfor _, e := range exts {\n\t\tif f := file + e; chkStat(f) == nil {\n\t\t\treturn f, nil\n\t\t}\n\t}\n\treturn \"\", fs.ErrNotExist\n}\n\n// LookPath searches for an executable named file in the\n// directories named by the PATH environment variable.\n// If file contains a slash, it is tried directly and the PATH is not consulted.\n// LookPath also uses PATHEXT environment variable to match\n// a suitable candidate.\n// The result may be an absolute path or a path relative to the current directory.\nfunc LookPath2(file string, lenv Env) (string, error) {\n\tvar exts []string\n\tx := lenv.Getenv(`PATHEXT`)\n\tif x != \"\" {\n\t\tfor _, e := range strings.Split(strings.ToLower(x), `;`) {\n\t\t\tif e == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif e[0] != '.' {\n\t\t\t\te = \".\" + e\n\t\t\t}\n\t\t\texts = append(exts, e)\n\t\t}\n\t} else {\n\t\texts = []string{\".com\", \".exe\", \".bat\", \".cmd\"}\n\t}\n\n\tif strings.ContainsAny(file, `:\\/`) {\n\t\tif f, err := findExecutable(file, exts); err == nil {\n\t\t\treturn f, nil\n\t\t} else {\n\t\t\treturn \"\", &Error{file, err}\n\t\t}\n\t}\n\tif f, err := findExecutable(filepath.Join(\".\", file), exts); err == nil {\n\t\treturn f, nil\n\t}\n\tpath := lenv.Getenv(\"path\")\n\tfor _, dir := range filepath.SplitList(path) {\n\t\tif f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {\n\t\t\treturn f, nil\n\t\t}\n\t}\n\treturn \"\", &Error{file, ErrNotFound}\n}\n"
  },
  {
    "path": "pkg/model/action.go",
    "content": "package model\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/schema\"\n\t\"gopkg.in/yaml.v3\"\n)\n\n// ActionRunsUsing is the type of runner for the action\ntype ActionRunsUsing string\n\nfunc (a *ActionRunsUsing) UnmarshalYAML(unmarshal func(interface{}) error) error {\n\tvar using string\n\tif err := unmarshal(&using); err != nil {\n\t\treturn err\n\t}\n\n\t// Force input to lowercase for case insensitive comparison\n\tformat := ActionRunsUsing(strings.ToLower(using))\n\tswitch format {\n\tcase ActionRunsUsingNode24, ActionRunsUsingNode20, ActionRunsUsingNode16, ActionRunsUsingNode12, ActionRunsUsingDocker, ActionRunsUsingComposite:\n\t\t*a = format\n\tdefault:\n\t\treturn fmt.Errorf(\"The runs.using key in action.yml must be one of: %v, got %s\", []string{\n\t\t\tActionRunsUsingComposite,\n\t\t\tActionRunsUsingDocker,\n\t\t\tActionRunsUsingNode12,\n\t\t\tActionRunsUsingNode16,\n\t\t\tActionRunsUsingNode20,\n\t\t\tActionRunsUsingNode24,\n\t\t}, format)\n\t}\n\treturn nil\n}\n\nconst (\n\t// ActionRunsUsingNode12 for running with node12\n\tActionRunsUsingNode12 = \"node12\"\n\t// ActionRunsUsingNode16 for running with node16\n\tActionRunsUsingNode16 = \"node16\"\n\t// ActionRunsUsingNode20 for running with node20\n\tActionRunsUsingNode20 = \"node20\"\n\t// ActionRunsUsingNode24 for running with node24\n\tActionRunsUsingNode24 = \"node24\"\n\t// ActionRunsUsingDocker for running with docker\n\tActionRunsUsingDocker = \"docker\"\n\t// ActionRunsUsingComposite for running composite\n\tActionRunsUsingComposite = \"composite\"\n)\n\nfunc (a ActionRunsUsing) IsNode() bool {\n\tswitch a {\n\tcase ActionRunsUsingNode12, ActionRunsUsingNode16, ActionRunsUsingNode20, ActionRunsUsingNode24:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (a ActionRunsUsing) IsDocker() bool {\n\treturn a == ActionRunsUsingDocker\n}\n\nfunc (a ActionRunsUsing) IsComposite() bool {\n\treturn a == ActionRunsUsingComposite\n}\n\n// ActionRuns are a field in Action\ntype ActionRuns struct {\n\tUsing          ActionRunsUsing   `yaml:\"using\"`\n\tEnv            map[string]string `yaml:\"env\"`\n\tMain           string            `yaml:\"main\"`\n\tPre            string            `yaml:\"pre\"`\n\tPreIf          string            `yaml:\"pre-if\"`\n\tPost           string            `yaml:\"post\"`\n\tPostIf         string            `yaml:\"post-if\"`\n\tImage          string            `yaml:\"image\"`\n\tPreEntrypoint  string            `yaml:\"pre-entrypoint\"`\n\tEntrypoint     string            `yaml:\"entrypoint\"`\n\tPostEntrypoint string            `yaml:\"post-entrypoint\"`\n\tArgs           []string          `yaml:\"args\"`\n\tSteps          []Step            `yaml:\"steps\"`\n}\n\n// Action describes a metadata file for GitHub actions. The metadata filename must be either action.yml or action.yaml. The data in the metadata file defines the inputs, outputs and main entrypoint for your action.\ntype Action struct {\n\tName        string            `yaml:\"name\"`\n\tAuthor      string            `yaml:\"author\"`\n\tDescription string            `yaml:\"description\"`\n\tInputs      map[string]Input  `yaml:\"inputs\"`\n\tOutputs     map[string]Output `yaml:\"outputs\"`\n\tRuns        ActionRuns        `yaml:\"runs\"`\n\tBranding    struct {\n\t\tColor string `yaml:\"color\"`\n\t\tIcon  string `yaml:\"icon\"`\n\t} `yaml:\"branding\"`\n}\n\nfunc (a *Action) UnmarshalYAML(node *yaml.Node) error {\n\t// TODO enable after verifying that this runner side feature has rolled out in actions/runner\n\t// // Resolve yaml anchor aliases first\n\t// if err := resolveAliases(node); err != nil {\n\t// \treturn err\n\t// }\n\t// Validate the schema before deserializing it into our model\n\tif err := (&schema.Node{\n\t\tDefinition: \"action-root\",\n\t\tSchema:     schema.GetActionSchema(),\n\t}).UnmarshalYAML(node); err != nil {\n\t\treturn err\n\t}\n\ttype ActionDefault Action\n\treturn node.Decode((*ActionDefault)(a))\n}\n\n// Input parameters allow you to specify data that the action expects to use during runtime. GitHub stores input parameters as environment variables. Input ids with uppercase letters are converted to lowercase during runtime. We recommended using lowercase input ids.\ntype Input struct {\n\tDescription string `yaml:\"description\"`\n\tRequired    bool   `yaml:\"required\"`\n\tDefault     string `yaml:\"default\"`\n}\n\n// Output parameters allow you to declare data that an action sets. Actions that run later in a workflow can use the output data set in previously run actions. For example, if you had an action that performed the addition of two inputs (x + y = z), the action could output the sum (z) for other actions to use as an input.\ntype Output struct {\n\tDescription string `yaml:\"description\"`\n\tValue       string `yaml:\"value\"`\n}\n\n// ReadAction reads an action from a reader\nfunc ReadAction(in io.Reader) (*Action, error) {\n\ta := new(Action)\n\terr := yaml.NewDecoder(in).Decode(a)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// set defaults\n\tif a.Runs.PreIf == \"\" {\n\t\ta.Runs.PreIf = \"always()\"\n\t}\n\tif a.Runs.PostIf == \"\" {\n\t\ta.Runs.PostIf = \"always()\"\n\t}\n\n\treturn a, nil\n}\n"
  },
  {
    "path": "pkg/model/anchors.go",
    "content": "package model\n\nimport (\n\t\"errors\"\n\n\t\"gopkg.in/yaml.v3\"\n)\n\nfunc resolveAliasesExt(node *yaml.Node, path map[*yaml.Node]bool, skipCheck bool) error {\n\tif !skipCheck && path[node] {\n\t\treturn errors.New(\"circular alias\")\n\t}\n\tswitch node.Kind {\n\tcase yaml.AliasNode:\n\t\taliasTarget := node.Alias\n\t\tif aliasTarget == nil {\n\t\t\treturn errors.New(\"unresolved alias node\")\n\t\t}\n\t\tpath[node] = true\n\t\t*node = *aliasTarget\n\t\tif err := resolveAliasesExt(node, path, true); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdelete(path, node)\n\n\tcase yaml.DocumentNode, yaml.MappingNode, yaml.SequenceNode:\n\t\tfor _, child := range node.Content {\n\t\t\tif err := resolveAliasesExt(child, path, false); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc resolveAliases(node *yaml.Node) error {\n\treturn resolveAliasesExt(node, map[*yaml.Node]bool{}, false)\n}\n"
  },
  {
    "path": "pkg/model/anchors_test.go",
    "content": "package model\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"gopkg.in/yaml.v3\"\n)\n\nfunc TestVerifyNilAliasError(t *testing.T) {\n\tvar node yaml.Node\n\terr := yaml.Unmarshal([]byte(`\ntest:\n- a\n- b\n- c`), &node)\n\t*node.Content[0].Content[1].Content[1] = yaml.Node{\n\t\tKind: yaml.AliasNode,\n\t}\n\tassert.NoError(t, err)\n\terr = resolveAliases(&node)\n\tassert.Error(t, err)\n}\n\nfunc TestVerifyNoRecursion(t *testing.T) {\n\ttable := []struct {\n\t\tname      string\n\t\tyaml      string\n\t\tyamlErr   bool\n\t\tanchorErr bool\n\t}{\n\t\t{\n\t\t\tname: \"no anchors\",\n\t\t\tyaml: `\na: x\nb: y\nc: z\n`,\n\t\t\tyamlErr:   false,\n\t\t\tanchorErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"simple anchors\",\n\t\t\tyaml: `\na: &a x\nb: &b y\nc: *a\n`,\n\t\t\tyamlErr:   false,\n\t\t\tanchorErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"nested anchors\",\n\t\t\tyaml: `\na: &a\n  val: x\nb: &b\n  val: y\nc: *a\n`,\n\t\t\tyamlErr:   false,\n\t\t\tanchorErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"circular anchors\",\n\t\t\tyaml: `\na: &b\n  ref: *c\nb: &c\n  ref: *b\n`,\n\t\t\tyamlErr:   true,\n\t\t\tanchorErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"self-referencing anchor\",\n\t\t\tyaml: `\na: &a\n  ref: *a\n`,\n\t\t\tyamlErr:   false,\n\t\t\tanchorErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"reuse snippet with anchors\",\n\t\t\tyaml: `\na: &b x\nb: &a\n   ref: *b\nc: *a\n`,\n\t\t\tyamlErr:   false,\n\t\t\tanchorErr: false,\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvar node yaml.Node\n\t\t\terr := yaml.Unmarshal([]byte(tt.yaml), &node)\n\t\t\tif tt.yamlErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tassert.NoError(t, err)\n\t\t\terr = resolveAliases(&node)\n\t\t\tif tt.anchorErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/model/github_context.go",
    "content": "package model\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/common/git\"\n)\n\ntype GithubContext struct {\n\tEvent            map[string]interface{} `json:\"event\"`\n\tEventPath        string                 `json:\"event_path\"`\n\tWorkflow         string                 `json:\"workflow\"`\n\tRunAttempt       string                 `json:\"run_attempt\"`\n\tRunID            string                 `json:\"run_id\"`\n\tRunNumber        string                 `json:\"run_number\"`\n\tActor            string                 `json:\"actor\"`\n\tRepository       string                 `json:\"repository\"`\n\tEventName        string                 `json:\"event_name\"`\n\tSha              string                 `json:\"sha\"`\n\tRef              string                 `json:\"ref\"`\n\tRefName          string                 `json:\"ref_name\"`\n\tRefType          string                 `json:\"ref_type\"`\n\tHeadRef          string                 `json:\"head_ref\"`\n\tBaseRef          string                 `json:\"base_ref\"`\n\tToken            string                 `json:\"token\"`\n\tWorkspace        string                 `json:\"workspace\"`\n\tAction           string                 `json:\"action\"`\n\tActionPath       string                 `json:\"action_path\"`\n\tActionRef        string                 `json:\"action_ref\"`\n\tActionRepository string                 `json:\"action_repository\"`\n\tJob              string                 `json:\"job\"`\n\tJobName          string                 `json:\"job_name\"`\n\tRepositoryOwner  string                 `json:\"repository_owner\"`\n\tRetentionDays    string                 `json:\"retention_days\"`\n\tRunnerPerflog    string                 `json:\"runner_perflog\"`\n\tRunnerTrackingID string                 `json:\"runner_tracking_id\"`\n\tServerURL        string                 `json:\"server_url\"`\n\tAPIURL           string                 `json:\"api_url\"`\n\tGraphQLURL       string                 `json:\"graphql_url\"`\n}\n\nfunc asString(v interface{}) string {\n\tif v == nil {\n\t\treturn \"\"\n\t} else if s, ok := v.(string); ok {\n\t\treturn s\n\t}\n\treturn \"\"\n}\n\nfunc nestedMapLookup(m map[string]interface{}, ks ...string) (rval interface{}) {\n\tvar ok bool\n\n\tif len(ks) == 0 { // degenerate input\n\t\treturn nil\n\t}\n\tif rval, ok = m[ks[0]]; !ok {\n\t\treturn nil\n\t} else if len(ks) == 1 { // we've reached the final key\n\t\treturn rval\n\t} else if m, ok = rval.(map[string]interface{}); !ok {\n\t\treturn nil\n\t}\n\t// 1+ more keys\n\treturn nestedMapLookup(m, ks[1:]...)\n}\n\nfunc withDefaultBranch(ctx context.Context, b string, event map[string]interface{}) map[string]interface{} {\n\trepoI, ok := event[\"repository\"]\n\tif !ok {\n\t\trepoI = make(map[string]interface{})\n\t}\n\n\trepo, ok := repoI.(map[string]interface{})\n\tif !ok {\n\t\tcommon.Logger(ctx).Warnf(\"unable to set default branch to %v\", b)\n\t\treturn event\n\t}\n\n\t// if the branch is already there return with no changes\n\tif _, ok = repo[\"default_branch\"]; ok {\n\t\treturn event\n\t}\n\n\trepo[\"default_branch\"] = b\n\tevent[\"repository\"] = repo\n\n\treturn event\n}\n\nvar findGitRef = git.FindGitRef\nvar findGitRevision = git.FindGitRevision\n\nfunc (ghc *GithubContext) SetRef(ctx context.Context, defaultBranch string, repoPath string) {\n\tlogger := common.Logger(ctx)\n\n\t// https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows\n\t// https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads\n\tswitch ghc.EventName {\n\tcase \"pull_request_target\":\n\t\tghc.Ref = fmt.Sprintf(\"refs/heads/%s\", ghc.BaseRef)\n\tcase \"pull_request\", \"pull_request_review\", \"pull_request_review_comment\":\n\t\tghc.Ref = fmt.Sprintf(\"refs/pull/%.0f/merge\", ghc.Event[\"number\"])\n\tcase \"deployment\", \"deployment_status\":\n\t\tghc.Ref = asString(nestedMapLookup(ghc.Event, \"deployment\", \"ref\"))\n\tcase \"release\":\n\t\tghc.Ref = fmt.Sprintf(\"refs/tags/%s\", asString(nestedMapLookup(ghc.Event, \"release\", \"tag_name\")))\n\tcase \"push\", \"create\", \"workflow_dispatch\":\n\t\tghc.Ref = asString(ghc.Event[\"ref\"])\n\tdefault:\n\t\tdefaultBranch := asString(nestedMapLookup(ghc.Event, \"repository\", \"default_branch\"))\n\t\tif defaultBranch != \"\" {\n\t\t\tghc.Ref = fmt.Sprintf(\"refs/heads/%s\", defaultBranch)\n\t\t}\n\t}\n\n\tif ghc.Ref == \"\" {\n\t\tref, err := findGitRef(ctx, repoPath)\n\t\tif err != nil {\n\t\t\tlogger.Warningf(\"unable to get git ref: %v\", err)\n\t\t} else {\n\t\t\tlogger.Debugf(\"using github ref: %s\", ref)\n\t\t\tghc.Ref = ref\n\t\t}\n\n\t\t// set the branch in the event data\n\t\tif defaultBranch != \"\" {\n\t\t\tghc.Event = withDefaultBranch(ctx, defaultBranch, ghc.Event)\n\t\t} else {\n\t\t\tghc.Event = withDefaultBranch(ctx, \"master\", ghc.Event)\n\t\t}\n\n\t\tif ghc.Ref == \"\" {\n\t\t\tghc.Ref = fmt.Sprintf(\"refs/heads/%s\", asString(nestedMapLookup(ghc.Event, \"repository\", \"default_branch\")))\n\t\t}\n\t}\n}\n\nfunc (ghc *GithubContext) SetSha(ctx context.Context, repoPath string) {\n\tlogger := common.Logger(ctx)\n\n\t// https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows\n\t// https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads\n\tswitch ghc.EventName {\n\tcase \"pull_request_target\":\n\t\tghc.Sha = asString(nestedMapLookup(ghc.Event, \"pull_request\", \"base\", \"sha\"))\n\tcase \"deployment\", \"deployment_status\":\n\t\tghc.Sha = asString(nestedMapLookup(ghc.Event, \"deployment\", \"sha\"))\n\tcase \"push\", \"create\", \"workflow_dispatch\":\n\t\tif deleted, ok := ghc.Event[\"deleted\"].(bool); ok && !deleted {\n\t\t\tghc.Sha = asString(ghc.Event[\"after\"])\n\t\t}\n\t}\n\n\tif ghc.Sha == \"\" {\n\t\t_, sha, err := findGitRevision(ctx, repoPath)\n\t\tif err != nil {\n\t\t\tlogger.Warningf(\"unable to get git revision: %v\", err)\n\t\t} else {\n\t\t\tghc.Sha = sha\n\t\t}\n\t}\n}\n\nfunc (ghc *GithubContext) SetRepositoryAndOwner(ctx context.Context, githubInstance string, remoteName string, repoPath string) {\n\tif ghc.Repository == \"\" {\n\t\trepo, err := git.FindGithubRepo(ctx, repoPath, githubInstance, remoteName)\n\t\tif err != nil {\n\t\t\tcommon.Logger(ctx).Debugf(\"unable to get git repo (githubInstance: %v; remoteName: %v, repoPath: %v): %v\", githubInstance, remoteName, repoPath, err)\n\t\t\t// nektos/act is used as a default action, so why not a repo?\n\t\t\tghc.Repository = \"nektos/act\"\n\t\t\tghc.RepositoryOwner = strings.Split(ghc.Repository, \"/\")[0]\n\t\t\treturn\n\t\t}\n\t\tghc.Repository = repo\n\t}\n\tghc.RepositoryOwner = strings.Split(ghc.Repository, \"/\")[0]\n}\n\nfunc (ghc *GithubContext) SetRefTypeAndName() {\n\tvar refType, refName string\n\n\t// https://docs.github.com/en/actions/learn-github-actions/environment-variables\n\tif strings.HasPrefix(ghc.Ref, \"refs/tags/\") {\n\t\trefType = \"tag\"\n\t\trefName = ghc.Ref[len(\"refs/tags/\"):]\n\t} else if strings.HasPrefix(ghc.Ref, \"refs/heads/\") {\n\t\trefType = \"branch\"\n\t\trefName = ghc.Ref[len(\"refs/heads/\"):]\n\t} else if strings.HasPrefix(ghc.Ref, \"refs/pull/\") {\n\t\trefType = \"\"\n\t\trefName = ghc.Ref[len(\"refs/pull/\"):]\n\t}\n\n\tif ghc.RefType == \"\" {\n\t\tghc.RefType = refType\n\t}\n\n\tif ghc.RefName == \"\" {\n\t\tghc.RefName = refName\n\t}\n}\n\nfunc (ghc *GithubContext) SetBaseAndHeadRef() {\n\tif ghc.EventName == \"pull_request\" || ghc.EventName == \"pull_request_target\" {\n\t\tif ghc.BaseRef == \"\" {\n\t\t\tghc.BaseRef = asString(nestedMapLookup(ghc.Event, \"pull_request\", \"base\", \"ref\"))\n\t\t}\n\n\t\tif ghc.HeadRef == \"\" {\n\t\t\tghc.HeadRef = asString(nestedMapLookup(ghc.Event, \"pull_request\", \"head\", \"ref\"))\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/model/github_context_test.go",
    "content": "package model\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestSetRef(t *testing.T) {\n\tlog.SetLevel(log.DebugLevel)\n\n\toldFindGitRef := findGitRef\n\toldFindGitRevision := findGitRevision\n\tdefer func() { findGitRef = oldFindGitRef }()\n\tdefer func() { findGitRevision = oldFindGitRevision }()\n\n\tfindGitRef = func(_ context.Context, _ string) (string, error) {\n\t\treturn \"refs/heads/master\", nil\n\t}\n\n\tfindGitRevision = func(_ context.Context, _ string) (string, string, error) {\n\t\treturn \"\", \"1234fakesha\", nil\n\t}\n\n\ttables := []struct {\n\t\teventName string\n\t\tevent     map[string]interface{}\n\t\tref       string\n\t\trefName   string\n\t}{\n\t\t{\n\t\t\teventName: \"pull_request_target\",\n\t\t\tevent:     map[string]interface{}{},\n\t\t\tref:       \"refs/heads/master\",\n\t\t\trefName:   \"master\",\n\t\t},\n\t\t{\n\t\t\teventName: \"pull_request\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"number\": 1234.,\n\t\t\t},\n\t\t\tref:     \"refs/pull/1234/merge\",\n\t\t\trefName: \"1234/merge\",\n\t\t},\n\t\t{\n\t\t\teventName: \"deployment\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"deployment\": map[string]interface{}{\n\t\t\t\t\t\"ref\": \"refs/heads/somebranch\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tref:     \"refs/heads/somebranch\",\n\t\t\trefName: \"somebranch\",\n\t\t},\n\t\t{\n\t\t\teventName: \"release\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"release\": map[string]interface{}{\n\t\t\t\t\t\"tag_name\": \"v1.0.0\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tref:     \"refs/tags/v1.0.0\",\n\t\t\trefName: \"v1.0.0\",\n\t\t},\n\t\t{\n\t\t\teventName: \"push\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"ref\": \"refs/heads/somebranch\",\n\t\t\t},\n\t\t\tref:     \"refs/heads/somebranch\",\n\t\t\trefName: \"somebranch\",\n\t\t},\n\t\t{\n\t\t\teventName: \"unknown\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"repository\": map[string]interface{}{\n\t\t\t\t\t\"default_branch\": \"main\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tref:     \"refs/heads/main\",\n\t\t\trefName: \"main\",\n\t\t},\n\t\t{\n\t\t\teventName: \"no-event\",\n\t\t\tevent:     map[string]interface{}{},\n\t\t\tref:       \"refs/heads/master\",\n\t\t\trefName:   \"master\",\n\t\t},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.eventName, func(t *testing.T) {\n\t\t\tghc := &GithubContext{\n\t\t\t\tEventName: table.eventName,\n\t\t\t\tBaseRef:   \"master\",\n\t\t\t\tEvent:     table.event,\n\t\t\t}\n\n\t\t\tghc.SetRef(context.Background(), \"main\", \"/some/dir\")\n\t\t\tghc.SetRefTypeAndName()\n\n\t\t\tassert.Equal(t, table.ref, ghc.Ref)\n\t\t\tassert.Equal(t, table.refName, ghc.RefName)\n\t\t})\n\t}\n\n\tt.Run(\"no-default-branch\", func(t *testing.T) {\n\t\tfindGitRef = func(_ context.Context, _ string) (string, error) {\n\t\t\treturn \"\", fmt.Errorf(\"no default branch\")\n\t\t}\n\n\t\tghc := &GithubContext{\n\t\t\tEventName: \"no-default-branch\",\n\t\t\tEvent:     map[string]interface{}{},\n\t\t}\n\n\t\tghc.SetRef(context.Background(), \"\", \"/some/dir\")\n\n\t\tassert.Equal(t, \"refs/heads/master\", ghc.Ref)\n\t})\n}\n\nfunc TestSetSha(t *testing.T) {\n\tlog.SetLevel(log.DebugLevel)\n\n\toldFindGitRef := findGitRef\n\toldFindGitRevision := findGitRevision\n\tdefer func() { findGitRef = oldFindGitRef }()\n\tdefer func() { findGitRevision = oldFindGitRevision }()\n\n\tfindGitRef = func(_ context.Context, _ string) (string, error) {\n\t\treturn \"refs/heads/master\", nil\n\t}\n\n\tfindGitRevision = func(_ context.Context, _ string) (string, string, error) {\n\t\treturn \"\", \"1234fakesha\", nil\n\t}\n\n\ttables := []struct {\n\t\teventName string\n\t\tevent     map[string]interface{}\n\t\tsha       string\n\t}{\n\t\t{\n\t\t\teventName: \"pull_request_target\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"pull_request\": map[string]interface{}{\n\t\t\t\t\t\"base\": map[string]interface{}{\n\t\t\t\t\t\t\"sha\": \"pr-base-sha\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tsha: \"pr-base-sha\",\n\t\t},\n\t\t{\n\t\t\teventName: \"pull_request\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"number\": 1234.,\n\t\t\t},\n\t\t\tsha: \"1234fakesha\",\n\t\t},\n\t\t{\n\t\t\teventName: \"deployment\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"deployment\": map[string]interface{}{\n\t\t\t\t\t\"sha\": \"deployment-sha\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tsha: \"deployment-sha\",\n\t\t},\n\t\t{\n\t\t\teventName: \"release\",\n\t\t\tevent:     map[string]interface{}{},\n\t\t\tsha:       \"1234fakesha\",\n\t\t},\n\t\t{\n\t\t\teventName: \"push\",\n\t\t\tevent: map[string]interface{}{\n\t\t\t\t\"after\":   \"push-sha\",\n\t\t\t\t\"deleted\": false,\n\t\t\t},\n\t\t\tsha: \"push-sha\",\n\t\t},\n\t\t{\n\t\t\teventName: \"unknown\",\n\t\t\tevent:     map[string]interface{}{},\n\t\t\tsha:       \"1234fakesha\",\n\t\t},\n\t\t{\n\t\t\teventName: \"no-event\",\n\t\t\tevent:     map[string]interface{}{},\n\t\t\tsha:       \"1234fakesha\",\n\t\t},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.eventName, func(t *testing.T) {\n\t\t\tghc := &GithubContext{\n\t\t\t\tEventName: table.eventName,\n\t\t\t\tBaseRef:   \"master\",\n\t\t\t\tEvent:     table.event,\n\t\t\t}\n\n\t\t\tghc.SetSha(context.Background(), \"/some/dir\")\n\n\t\t\tassert.Equal(t, table.sha, ghc.Sha)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/model/job_context.go",
    "content": "package model\n\ntype JobContext struct {\n\tStatus    string `json:\"status\"`\n\tContainer struct {\n\t\tID      string `json:\"id\"`\n\t\tNetwork string `json:\"network\"`\n\t} `json:\"container\"`\n\tServices map[string]struct {\n\t\tID string `json:\"id\"`\n\t} `json:\"services\"`\n}\n"
  },
  {
    "path": "pkg/model/planner.go",
    "content": "package model\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"math\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"sort\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// WorkflowPlanner contains methods for creating plans\ntype WorkflowPlanner interface {\n\tPlanEvent(eventName string) (*Plan, error)\n\tPlanJob(jobName string) (*Plan, error)\n\tPlanAll() (*Plan, error)\n\tGetEvents() []string\n}\n\n// Plan contains a list of stages to run in series\ntype Plan struct {\n\tStages []*Stage\n}\n\n// Stage contains a list of runs to execute in parallel\ntype Stage struct {\n\tRuns []*Run\n}\n\n// Run represents a job from a workflow that needs to be run\ntype Run struct {\n\tWorkflow *Workflow\n\tJobID    string\n}\n\nfunc (r *Run) String() string {\n\tjobName := r.Job().Name\n\tif jobName == \"\" {\n\t\tjobName = r.JobID\n\t}\n\treturn jobName\n}\n\n// Job returns the job for this Run\nfunc (r *Run) Job() *Job {\n\treturn r.Workflow.GetJob(r.JobID)\n}\n\ntype WorkflowFiles struct {\n\tworkflowDirEntry os.DirEntry\n\tdirPath          string\n}\n\n// NewWorkflowPlanner will load a specific workflow, all workflows from a directory or all workflows from a directory and its subdirectories\nfunc NewWorkflowPlanner(path string, noWorkflowRecurse, strict bool) (WorkflowPlanner, error) {\n\tpath, err := filepath.Abs(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfi, err := os.Stat(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar workflows []WorkflowFiles\n\n\tif fi.IsDir() {\n\t\tlog.Debugf(\"Loading workflows from '%s'\", path)\n\t\tif noWorkflowRecurse {\n\t\t\tfiles, err := os.ReadDir(path)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tfor _, v := range files {\n\t\t\t\tworkflows = append(workflows, WorkflowFiles{\n\t\t\t\t\tdirPath:          path,\n\t\t\t\t\tworkflowDirEntry: v,\n\t\t\t\t})\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debug(\"Loading workflows recursively\")\n\t\t\tif err := filepath.Walk(path,\n\t\t\t\tfunc(p string, f os.FileInfo, err error) error {\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\n\t\t\t\t\tif !f.IsDir() {\n\t\t\t\t\t\tlog.Debugf(\"Found workflow '%s' in '%s'\", f.Name(), p)\n\t\t\t\t\t\tworkflows = append(workflows, WorkflowFiles{\n\t\t\t\t\t\t\tdirPath:          filepath.Dir(p),\n\t\t\t\t\t\t\tworkflowDirEntry: fs.FileInfoToDirEntry(f),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn nil\n\t\t\t\t}); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlog.Debugf(\"Loading workflow '%s'\", path)\n\t\tdirname := filepath.Dir(path)\n\n\t\tworkflows = append(workflows, WorkflowFiles{\n\t\t\tdirPath:          dirname,\n\t\t\tworkflowDirEntry: fs.FileInfoToDirEntry(fi),\n\t\t})\n\t}\n\n\twp := new(workflowPlanner)\n\tfor _, wf := range workflows {\n\t\text := filepath.Ext(wf.workflowDirEntry.Name())\n\t\tif ext == \".yml\" || ext == \".yaml\" {\n\t\t\tf, err := os.Open(filepath.Join(wf.dirPath, wf.workflowDirEntry.Name()))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tlog.Debugf(\"Reading workflow '%s'\", f.Name())\n\t\t\tworkflow, err := ReadWorkflow(f, strict)\n\t\t\tif err != nil {\n\t\t\t\t_ = f.Close()\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\treturn nil, fmt.Errorf(\"unable to read workflow '%s': file is empty: %w\", wf.workflowDirEntry.Name(), err)\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"workflow is not valid. '%s': %w\", wf.workflowDirEntry.Name(), err)\n\t\t\t}\n\t\t\t_, err = f.Seek(0, 0)\n\t\t\tif err != nil {\n\t\t\t\t_ = f.Close()\n\t\t\t\treturn nil, fmt.Errorf(\"error occurring when resetting io pointer in '%s': %w\", wf.workflowDirEntry.Name(), err)\n\t\t\t}\n\n\t\t\tworkflow.File = wf.workflowDirEntry.Name()\n\t\t\tif workflow.Name == \"\" {\n\t\t\t\tworkflow.Name = wf.workflowDirEntry.Name()\n\t\t\t}\n\n\t\t\terr = validateJobName(workflow)\n\t\t\tif err != nil {\n\t\t\t\t_ = f.Close()\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\twp.workflows = append(wp.workflows, workflow)\n\t\t\t_ = f.Close()\n\t\t}\n\t}\n\n\treturn wp, nil\n}\n\nfunc NewSingleWorkflowPlanner(name string, f io.Reader) (WorkflowPlanner, error) {\n\twp := new(workflowPlanner)\n\n\tlog.Debugf(\"Reading workflow %s\", name)\n\tworkflow, err := ReadWorkflow(f, false)\n\tif err != nil {\n\t\tif err == io.EOF {\n\t\t\treturn nil, fmt.Errorf(\"unable to read workflow '%s': file is empty: %w\", name, err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"workflow is not valid. '%s': %w\", name, err)\n\t}\n\tworkflow.File = name\n\tif workflow.Name == \"\" {\n\t\tworkflow.Name = name\n\t}\n\n\terr = validateJobName(workflow)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\twp.workflows = append(wp.workflows, workflow)\n\n\treturn wp, nil\n}\n\nfunc validateJobName(workflow *Workflow) error {\n\tjobNameRegex := regexp.MustCompile(`^([[:alpha:]_][[:alnum:]_\\-]*)$`)\n\tfor k := range workflow.Jobs {\n\t\tif ok := jobNameRegex.MatchString(k); !ok {\n\t\t\treturn fmt.Errorf(\"workflow is not valid. '%s': Job name '%s' is invalid. Names must start with a letter or '_' and contain only alphanumeric characters, '-', or '_'\", workflow.Name, k)\n\t\t}\n\t}\n\treturn nil\n}\n\ntype workflowPlanner struct {\n\tworkflows []*Workflow\n}\n\n// PlanEvent builds a new list of runs to execute in parallel for an event name\nfunc (wp *workflowPlanner) PlanEvent(eventName string) (*Plan, error) {\n\tplan := new(Plan)\n\tif len(wp.workflows) == 0 {\n\t\tlog.Debug(\"no workflows found by planner\")\n\t\treturn plan, nil\n\t}\n\tvar lastErr error\n\n\tfor _, w := range wp.workflows {\n\t\tevents := w.On()\n\t\tif len(events) == 0 {\n\t\t\tlog.Debugf(\"no events found for workflow: %s\", w.File)\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, e := range events {\n\t\t\tif e == eventName {\n\t\t\t\tstages, err := createStages(w, w.GetJobIDs()...)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Warn(err)\n\t\t\t\t\tlastErr = err\n\t\t\t\t} else {\n\t\t\t\t\tplan.mergeStages(stages)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn plan, lastErr\n}\n\n// PlanJob builds a new run to execute in parallel for a job name\nfunc (wp *workflowPlanner) PlanJob(jobName string) (*Plan, error) {\n\tplan := new(Plan)\n\tif len(wp.workflows) == 0 {\n\t\tlog.Debugf(\"no jobs found for workflow: %s\", jobName)\n\t}\n\tvar lastErr error\n\n\tfor _, w := range wp.workflows {\n\t\tstages, err := createStages(w, jobName)\n\t\tif err != nil {\n\t\t\tlog.Warn(err)\n\t\t\tlastErr = err\n\t\t} else {\n\t\t\tplan.mergeStages(stages)\n\t\t}\n\t}\n\treturn plan, lastErr\n}\n\n// PlanAll builds a new run to execute in parallel all\nfunc (wp *workflowPlanner) PlanAll() (*Plan, error) {\n\tplan := new(Plan)\n\tif len(wp.workflows) == 0 {\n\t\tlog.Debug(\"no workflows found by planner\")\n\t\treturn plan, nil\n\t}\n\tvar lastErr error\n\n\tfor _, w := range wp.workflows {\n\t\tstages, err := createStages(w, w.GetJobIDs()...)\n\t\tif err != nil {\n\t\t\tlog.Warn(err)\n\t\t\tlastErr = err\n\t\t} else {\n\t\t\tplan.mergeStages(stages)\n\t\t}\n\t}\n\n\treturn plan, lastErr\n}\n\n// GetEvents gets all the events in the workflows file\nfunc (wp *workflowPlanner) GetEvents() []string {\n\tevents := make([]string, 0)\n\tfor _, w := range wp.workflows {\n\t\tfound := false\n\t\tfor _, e := range events {\n\t\t\tfor _, we := range w.On() {\n\t\t\t\tif e == we {\n\t\t\t\t\tfound = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif found {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif !found {\n\t\t\tevents = append(events, w.On()...)\n\t\t}\n\t}\n\n\t// sort the list based on depth of dependencies\n\tsort.Slice(events, func(i, j int) bool {\n\t\treturn events[i] < events[j]\n\t})\n\n\treturn events\n}\n\n// MaxRunNameLen determines the max name length of all jobs\nfunc (p *Plan) MaxRunNameLen() int {\n\tmaxRunNameLen := 0\n\tfor _, stage := range p.Stages {\n\t\tfor _, run := range stage.Runs {\n\t\t\trunNameLen := len(run.String())\n\t\t\tif runNameLen > maxRunNameLen {\n\t\t\t\tmaxRunNameLen = runNameLen\n\t\t\t}\n\t\t}\n\t}\n\treturn maxRunNameLen\n}\n\n// GetJobIDs will get all the job names in the stage\nfunc (s *Stage) GetJobIDs() []string {\n\tnames := make([]string, 0)\n\tfor _, r := range s.Runs {\n\t\tnames = append(names, r.JobID)\n\t}\n\treturn names\n}\n\n// Merge stages with existing stages in plan\nfunc (p *Plan) mergeStages(stages []*Stage) {\n\tnewStages := make([]*Stage, int(math.Max(float64(len(p.Stages)), float64(len(stages)))))\n\tfor i := 0; i < len(newStages); i++ {\n\t\tnewStages[i] = new(Stage)\n\t\tif i >= len(p.Stages) {\n\t\t\tnewStages[i].Runs = append(newStages[i].Runs, stages[i].Runs...)\n\t\t} else if i >= len(stages) {\n\t\t\tnewStages[i].Runs = append(newStages[i].Runs, p.Stages[i].Runs...)\n\t\t} else {\n\t\t\tnewStages[i].Runs = append(newStages[i].Runs, p.Stages[i].Runs...)\n\t\t\tnewStages[i].Runs = append(newStages[i].Runs, stages[i].Runs...)\n\t\t}\n\t}\n\tp.Stages = newStages\n}\n\nfunc createStages(w *Workflow, jobIDs ...string) ([]*Stage, error) {\n\t// first, build a list of all the necessary jobs to run, and their dependencies\n\tjobDependencies := make(map[string][]string)\n\tfor len(jobIDs) > 0 {\n\t\tnewJobIDs := make([]string, 0)\n\t\tfor _, jID := range jobIDs {\n\t\t\t// make sure we haven't visited this job yet\n\t\t\tif _, ok := jobDependencies[jID]; !ok {\n\t\t\t\tif job := w.GetJob(jID); job != nil {\n\t\t\t\t\tjobDependencies[jID] = job.Needs()\n\t\t\t\t\tnewJobIDs = append(newJobIDs, job.Needs()...)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tjobIDs = newJobIDs\n\t}\n\n\t// next, build an execution graph\n\tstages := make([]*Stage, 0)\n\tfor len(jobDependencies) > 0 {\n\t\tstage := new(Stage)\n\t\tfor jID, jDeps := range jobDependencies {\n\t\t\t// make sure all deps are in the graph already\n\t\t\tif listInStages(jDeps, stages...) {\n\t\t\t\tstage.Runs = append(stage.Runs, &Run{\n\t\t\t\t\tWorkflow: w,\n\t\t\t\t\tJobID:    jID,\n\t\t\t\t})\n\t\t\t\tdelete(jobDependencies, jID)\n\t\t\t}\n\t\t}\n\t\tif len(stage.Runs) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"unable to build dependency graph for %s (%s)\", w.Name, w.File)\n\t\t}\n\t\tstages = append(stages, stage)\n\t}\n\n\treturn stages, nil\n}\n\n// return true iff all strings in srcList exist in at least one of the stages\nfunc listInStages(srcList []string, stages ...*Stage) bool {\n\tfor _, src := range srcList {\n\t\tfound := false\n\t\tfor _, stage := range stages {\n\t\t\tfor _, search := range stage.GetJobIDs() {\n\t\t\t\tif src == search {\n\t\t\t\t\tfound = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "pkg/model/planner_test.go",
    "content": "package model\n\nimport (\n\t\"path/filepath\"\n\t\"testing\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\ntype WorkflowPlanTest struct {\n\tworkflowPath      string\n\terrorMessage      string\n\tnoWorkflowRecurse bool\n}\n\nfunc TestPlanner(t *testing.T) {\n\tlog.SetLevel(log.DebugLevel)\n\n\ttables := []WorkflowPlanTest{\n\t\t{\"invalid-job-name/invalid-1.yml\", \"workflow is not valid. 'invalid-job-name-1': Job name 'invalid-JOB-Name-v1.2.3-docker_hub' is invalid. Names must start with a letter or '_' and contain only alphanumeric characters, '-', or '_'\", false},\n\t\t{\"invalid-job-name/invalid-2.yml\", \"workflow is not valid. 'invalid-job-name-2': Job name '1234invalid-JOB-Name-v123-docker_hub' is invalid. Names must start with a letter or '_' and contain only alphanumeric characters, '-', or '_'\", false},\n\t\t{\"invalid-job-name/valid-1.yml\", \"\", false},\n\t\t{\"invalid-job-name/valid-2.yml\", \"\", false},\n\t\t{\"empty-workflow\", \"unable to read workflow 'push.yml': file is empty: EOF\", false},\n\t\t{\"nested\", \"unable to read workflow 'fail.yml': file is empty: EOF\", false},\n\t\t{\"nested\", \"\", true},\n\t}\n\n\tworkdir, err := filepath.Abs(\"testdata\")\n\tassert.NoError(t, err, workdir)\n\tfor _, table := range tables {\n\t\tfullWorkflowPath := filepath.Join(workdir, table.workflowPath)\n\t\t_, err = NewWorkflowPlanner(fullWorkflowPath, table.noWorkflowRecurse, false)\n\t\tif table.errorMessage == \"\" {\n\t\t\tassert.NoError(t, err, \"WorkflowPlanner should exit without any error\")\n\t\t} else {\n\t\t\tassert.EqualError(t, err, table.errorMessage)\n\t\t}\n\t}\n}\n\nfunc TestWorkflow(t *testing.T) {\n\tlog.SetLevel(log.DebugLevel)\n\n\tworkflow := Workflow{\n\t\tJobs: map[string]*Job{\n\t\t\t\"valid_job\": {\n\t\t\t\tName: \"valid_job\",\n\t\t\t},\n\t\t},\n\t}\n\n\t// Check that a valid job id returns non-error\n\tresult, err := createStages(&workflow, \"valid_job\")\n\tassert.Nil(t, err)\n\tassert.NotNil(t, result)\n}\n"
  },
  {
    "path": "pkg/model/step_result.go",
    "content": "package model\n\nimport \"fmt\"\n\ntype stepStatus int\n\nconst (\n\tStepStatusSuccess stepStatus = iota\n\tStepStatusFailure\n\tStepStatusSkipped\n)\n\nvar stepStatusStrings = [...]string{\n\t\"success\",\n\t\"failure\",\n\t\"skipped\",\n}\n\nfunc (s stepStatus) MarshalText() ([]byte, error) {\n\treturn []byte(s.String()), nil\n}\n\nfunc (s *stepStatus) UnmarshalText(b []byte) error {\n\tstr := string(b)\n\tfor i, name := range stepStatusStrings {\n\t\tif name == str {\n\t\t\t*s = stepStatus(i)\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn fmt.Errorf(\"invalid step status %q\", str)\n}\n\nfunc (s stepStatus) String() string {\n\tif int(s) >= len(stepStatusStrings) {\n\t\treturn \"\"\n\t}\n\treturn stepStatusStrings[s]\n}\n\ntype StepResult struct {\n\tOutputs    map[string]string `json:\"outputs\"`\n\tConclusion stepStatus        `json:\"conclusion\"`\n\tOutcome    stepStatus        `json:\"outcome\"`\n}\n"
  },
  {
    "path": "pkg/model/testdata/container-volumes/push.yml",
    "content": "name: Job Container\non: push\n\njobs:\n  with-volumes:\n    runs-on: ubuntu-latest\n    container:\n      image: node:16-buster-slim\n      volumes:\n        - my_docker_volume:/path/to/volume\n        - /path/to/nonexist/directory\n        - /proc/sys/kernel/random/boot_id:/current/boot_id\n    steps:\n      - run: |\n          set -e\n          test -d /path/to/volume\n          test \"$(cat /proc/sys/kernel/random/boot_id)\" = \"$(cat /current/boot_id)\"\n          test -d /path/to/nonexist/directory\n  "
  },
  {
    "path": "pkg/model/testdata/empty-workflow/push.yml",
    "content": ""
  },
  {
    "path": "pkg/model/testdata/invalid-job-name/invalid-1.yml",
    "content": "name: invalid-job-name-1\non: push\n\njobs:\n  invalid-JOB-Name-v1.2.3-docker_hub:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo hi\n  valid-JOB-Name-v123-docker_hub:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo hi\n"
  },
  {
    "path": "pkg/model/testdata/invalid-job-name/invalid-2.yml",
    "content": "name: invalid-job-name-2\non: push\n\njobs:\n  1234invalid-JOB-Name-v123-docker_hub:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo hi\n"
  },
  {
    "path": "pkg/model/testdata/invalid-job-name/valid-1.yml",
    "content": "name: valid-job-name-1\non: push\n\njobs:\n  valid-JOB-Name-v123-docker_hub:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo hi\n"
  },
  {
    "path": "pkg/model/testdata/invalid-job-name/valid-2.yml",
    "content": "name: valid-job-name-2\non: push\n\njobs:\n  ___valid-JOB-Name-v123-docker_hub:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo hi\n"
  },
  {
    "path": "pkg/model/testdata/nested/success.yml",
    "content": "name: Hello World Workflow\non: push\n\njobs:\n  hello-world:\n    name: Hello World Job\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"Hello World!\"\n"
  },
  {
    "path": "pkg/model/testdata/nested/workflows/fail.yml",
    "content": ""
  },
  {
    "path": "pkg/model/testdata/strategy/push.yml",
    "content": "---\njobs:\n  strategy-all:\n    name: ${{ matrix.node-version }} | ${{ matrix.site }} | ${{ matrix.datacenter }}\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo 'Hello!'\n    strategy:\n      fail-fast: false\n      matrix:\n        datacenter:\n          - site-c\n          - site-d\n        exclude:\n          - datacenter: site-d\n            node-version: 14.x\n            site: staging\n        include:\n          - php-version: 5.4\n          - datacenter: site-a\n            node-version: 10.x\n            site: prod\n          - datacenter: site-b\n            node-version: 12.x\n            site: dev\n        node-version: [14.x, 16.x]\n        site:\n          - staging\n      max-parallel: 2\n  strategy-no-matrix:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo 'Hello!'\n    strategy:\n      fail-fast: false\n      max-parallel: 2\n  strategy-only-fail-fast:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo 'Hello!'\n    strategy:\n      fail-fast: false\n  strategy-only-max-parallel:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo 'Hello!'\n    strategy:\n      max-parallel: 2\n'on':\n  push: null\n"
  },
  {
    "path": "pkg/model/workflow.go",
    "content": "package model\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/schema\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"gopkg.in/yaml.v3\"\n)\n\n// Workflow is the structure of the files in .github/workflows\ntype Workflow struct {\n\tFile     string\n\tName     string            `yaml:\"name\"`\n\tRawOn    yaml.Node         `yaml:\"on\"`\n\tEnv      map[string]string `yaml:\"env\"`\n\tJobs     map[string]*Job   `yaml:\"jobs\"`\n\tDefaults Defaults          `yaml:\"defaults\"`\n}\n\n// On events for the workflow\nfunc (w *Workflow) On() []string {\n\tswitch w.RawOn.Kind {\n\tcase yaml.ScalarNode:\n\t\tvar val string\n\t\terr := w.RawOn.Decode(&val)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\treturn []string{val}\n\tcase yaml.SequenceNode:\n\t\tvar val []string\n\t\terr := w.RawOn.Decode(&val)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\treturn val\n\tcase yaml.MappingNode:\n\t\tvar val map[string]interface{}\n\t\terr := w.RawOn.Decode(&val)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tvar keys []string\n\t\tfor k := range val {\n\t\t\tkeys = append(keys, k)\n\t\t}\n\t\treturn keys\n\t}\n\treturn nil\n}\n\nfunc (w *Workflow) OnEvent(event string) interface{} {\n\tif w.RawOn.Kind == yaml.MappingNode {\n\t\tvar val map[string]interface{}\n\t\tif !decodeNode(w.RawOn, &val) {\n\t\t\treturn nil\n\t\t}\n\t\treturn val[event]\n\t}\n\treturn nil\n}\n\nfunc (w *Workflow) UnmarshalYAML(node *yaml.Node) error {\n\t// Resolve yaml anchor aliases first\n\tif err := resolveAliases(node); err != nil {\n\t\treturn err\n\t}\n\t// Validate the schema before deserializing it into our model\n\tif err := (&schema.Node{\n\t\tDefinition: \"workflow-root\",\n\t\tSchema:     schema.GetWorkflowSchema(),\n\t}).UnmarshalYAML(node); err != nil {\n\t\treturn errors.Join(err, fmt.Errorf(\"Actions YAML Schema Validation Error detected:\\nFor more information, see: https://nektosact.com/usage/schema.html\"))\n\t}\n\ttype WorkflowDefault Workflow\n\treturn node.Decode((*WorkflowDefault)(w))\n}\n\ntype WorkflowStrict Workflow\n\nfunc (w *WorkflowStrict) UnmarshalYAML(node *yaml.Node) error {\n\t// Resolve yaml anchor aliases first\n\tif err := resolveAliases(node); err != nil {\n\t\treturn err\n\t}\n\t// Validate the schema before deserializing it into our model\n\tif err := (&schema.Node{\n\t\tDefinition: \"workflow-root-strict\",\n\t\tSchema:     schema.GetWorkflowSchema(),\n\t}).UnmarshalYAML(node); err != nil {\n\t\treturn errors.Join(err, fmt.Errorf(\"Actions YAML Strict Schema Validation Error detected:\\nFor more information, see: https://nektosact.com/usage/schema.html\"))\n\t}\n\ttype WorkflowDefault Workflow\n\treturn node.Decode((*WorkflowDefault)(w))\n}\n\ntype WorkflowDispatchInput struct {\n\tDescription string   `yaml:\"description\"`\n\tRequired    bool     `yaml:\"required\"`\n\tDefault     string   `yaml:\"default\"`\n\tType        string   `yaml:\"type\"`\n\tOptions     []string `yaml:\"options\"`\n}\n\ntype WorkflowDispatch struct {\n\tInputs map[string]WorkflowDispatchInput `yaml:\"inputs\"`\n}\n\nfunc (w *Workflow) WorkflowDispatchConfig() *WorkflowDispatch {\n\tswitch w.RawOn.Kind {\n\tcase yaml.ScalarNode:\n\t\tvar val string\n\t\tif !decodeNode(w.RawOn, &val) {\n\t\t\treturn nil\n\t\t}\n\t\tif val == \"workflow_dispatch\" {\n\t\t\treturn &WorkflowDispatch{}\n\t\t}\n\tcase yaml.SequenceNode:\n\t\tvar val []string\n\t\tif !decodeNode(w.RawOn, &val) {\n\t\t\treturn nil\n\t\t}\n\t\tfor _, v := range val {\n\t\t\tif v == \"workflow_dispatch\" {\n\t\t\t\treturn &WorkflowDispatch{}\n\t\t\t}\n\t\t}\n\tcase yaml.MappingNode:\n\t\tvar val map[string]yaml.Node\n\t\tif !decodeNode(w.RawOn, &val) {\n\t\t\treturn nil\n\t\t}\n\n\t\tn, found := val[\"workflow_dispatch\"]\n\t\tvar workflowDispatch WorkflowDispatch\n\t\tif found && decodeNode(n, &workflowDispatch) {\n\t\t\treturn &workflowDispatch\n\t\t}\n\tdefault:\n\t\treturn nil\n\t}\n\treturn nil\n}\n\ntype WorkflowCallInput struct {\n\tDescription string    `yaml:\"description\"`\n\tRequired    bool      `yaml:\"required\"`\n\tDefault     yaml.Node `yaml:\"default\"`\n\tType        string    `yaml:\"type\"`\n}\n\ntype WorkflowCallOutput struct {\n\tDescription string `yaml:\"description\"`\n\tValue       string `yaml:\"value\"`\n}\n\ntype WorkflowCall struct {\n\tInputs  map[string]WorkflowCallInput  `yaml:\"inputs\"`\n\tOutputs map[string]WorkflowCallOutput `yaml:\"outputs\"`\n}\n\ntype WorkflowCallResult struct {\n\tOutputs map[string]string\n}\n\nfunc (w *Workflow) WorkflowCallConfig() *WorkflowCall {\n\tif w.RawOn.Kind != yaml.MappingNode {\n\t\t// The callers expect for \"on: workflow_call\" and \"on: [ workflow_call ]\" a non nil return value\n\t\treturn &WorkflowCall{}\n\t}\n\n\tvar val map[string]yaml.Node\n\tif !decodeNode(w.RawOn, &val) {\n\t\treturn &WorkflowCall{}\n\t}\n\n\tvar config WorkflowCall\n\tnode := val[\"workflow_call\"]\n\tif !decodeNode(node, &config) {\n\t\treturn &WorkflowCall{}\n\t}\n\n\treturn &config\n}\n\n// Job is the structure of one job in a workflow\ntype Job struct {\n\tName           string                    `yaml:\"name\"`\n\tRawNeeds       yaml.Node                 `yaml:\"needs\"`\n\tRawRunsOn      yaml.Node                 `yaml:\"runs-on\"`\n\tEnv            yaml.Node                 `yaml:\"env\"`\n\tIf             yaml.Node                 `yaml:\"if\"`\n\tSteps          []*Step                   `yaml:\"steps\"`\n\tTimeoutMinutes string                    `yaml:\"timeout-minutes\"`\n\tServices       map[string]*ContainerSpec `yaml:\"services\"`\n\tStrategy       *Strategy                 `yaml:\"strategy\"`\n\tRawContainer   yaml.Node                 `yaml:\"container\"`\n\tDefaults       Defaults                  `yaml:\"defaults\"`\n\tOutputs        map[string]string         `yaml:\"outputs\"`\n\tUses           string                    `yaml:\"uses\"`\n\tWith           map[string]interface{}    `yaml:\"with\"`\n\tRawSecrets     yaml.Node                 `yaml:\"secrets\"`\n\tResult         string\n}\n\n// Strategy for the job\ntype Strategy struct {\n\tFailFast          bool\n\tMaxParallel       int\n\tFailFastString    string    `yaml:\"fail-fast\"`\n\tMaxParallelString string    `yaml:\"max-parallel\"`\n\tRawMatrix         yaml.Node `yaml:\"matrix\"`\n}\n\n// Default settings that will apply to all steps in the job or workflow\ntype Defaults struct {\n\tRun RunDefaults `yaml:\"run\"`\n}\n\n// Defaults for all run steps in the job or workflow\ntype RunDefaults struct {\n\tShell            string `yaml:\"shell\"`\n\tWorkingDirectory string `yaml:\"working-directory\"`\n}\n\n// GetMaxParallel sets default and returns value for `max-parallel`\nfunc (s Strategy) GetMaxParallel() int {\n\t// MaxParallel default value is `GitHub will maximize the number of jobs run in parallel depending on the available runners on GitHub-hosted virtual machines`\n\t// So I take the liberty to hardcode default limit to 4 and this is because:\n\t// 1: tl;dr: self-hosted does only 1 parallel job - https://github.com/actions/runner/issues/639#issuecomment-825212735\n\t// 2: GH has 20 parallel job limit (for free tier) - https://github.com/github/docs/blob/3ae84420bd10997bb5f35f629ebb7160fe776eae/content/actions/reference/usage-limits-billing-and-administration.md?plain=1#L45\n\t// 3: I want to add support for MaxParallel to act and 20! parallel jobs is a bit overkill IMHO\n\tmaxParallel := 4\n\tif s.MaxParallelString != \"\" {\n\t\tvar err error\n\t\tif maxParallel, err = strconv.Atoi(s.MaxParallelString); err != nil {\n\t\t\tlog.Errorf(\"Failed to parse 'max-parallel' option: %v\", err)\n\t\t}\n\t}\n\treturn maxParallel\n}\n\n// GetFailFast sets default and returns value for `fail-fast`\nfunc (s Strategy) GetFailFast() bool {\n\t// FailFast option is true by default: https://github.com/github/docs/blob/3ae84420bd10997bb5f35f629ebb7160fe776eae/content/actions/reference/workflow-syntax-for-github-actions.md?plain=1#L1107\n\tfailFast := true\n\tlog.Debug(s.FailFastString)\n\tif s.FailFastString != \"\" {\n\t\tvar err error\n\t\tif failFast, err = strconv.ParseBool(s.FailFastString); err != nil {\n\t\t\tlog.Errorf(\"Failed to parse 'fail-fast' option: %v\", err)\n\t\t}\n\t}\n\treturn failFast\n}\n\nfunc (j *Job) InheritSecrets() bool {\n\tif j.RawSecrets.Kind != yaml.ScalarNode {\n\t\treturn false\n\t}\n\n\tvar val string\n\tif !decodeNode(j.RawSecrets, &val) {\n\t\treturn false\n\t}\n\n\treturn val == \"inherit\"\n}\n\nfunc (j *Job) Secrets() map[string]string {\n\tif j.RawSecrets.Kind != yaml.MappingNode {\n\t\treturn nil\n\t}\n\n\tvar val map[string]string\n\tif !decodeNode(j.RawSecrets, &val) {\n\t\treturn nil\n\t}\n\n\treturn val\n}\n\n// Container details for the job\nfunc (j *Job) Container() *ContainerSpec {\n\tvar val *ContainerSpec\n\tswitch j.RawContainer.Kind {\n\tcase yaml.ScalarNode:\n\t\tval = new(ContainerSpec)\n\t\tif !decodeNode(j.RawContainer, &val.Image) {\n\t\t\treturn nil\n\t\t}\n\tcase yaml.MappingNode:\n\t\tval = new(ContainerSpec)\n\t\tif !decodeNode(j.RawContainer, val) {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn val\n}\n\n// Needs list for Job\nfunc (j *Job) Needs() []string {\n\tswitch j.RawNeeds.Kind {\n\tcase yaml.ScalarNode:\n\t\tvar val string\n\t\tif !decodeNode(j.RawNeeds, &val) {\n\t\t\treturn nil\n\t\t}\n\t\treturn []string{val}\n\tcase yaml.SequenceNode:\n\t\tvar val []string\n\t\tif !decodeNode(j.RawNeeds, &val) {\n\t\t\treturn nil\n\t\t}\n\t\treturn val\n\t}\n\treturn nil\n}\n\n// RunsOn list for Job\nfunc (j *Job) RunsOn() []string {\n\tswitch j.RawRunsOn.Kind {\n\tcase yaml.MappingNode:\n\t\tvar val struct {\n\t\t\tGroup  string\n\t\t\tLabels yaml.Node\n\t\t}\n\n\t\tif !decodeNode(j.RawRunsOn, &val) {\n\t\t\treturn nil\n\t\t}\n\n\t\tlabels := nodeAsStringSlice(val.Labels)\n\n\t\tif val.Group != \"\" {\n\t\t\tlabels = append(labels, val.Group)\n\t\t}\n\n\t\treturn labels\n\tdefault:\n\t\treturn nodeAsStringSlice(j.RawRunsOn)\n\t}\n}\n\nfunc nodeAsStringSlice(node yaml.Node) []string {\n\tswitch node.Kind {\n\tcase yaml.ScalarNode:\n\t\tvar val string\n\t\tif !decodeNode(node, &val) {\n\t\t\treturn nil\n\t\t}\n\t\treturn []string{val}\n\tcase yaml.SequenceNode:\n\t\tvar val []string\n\t\tif !decodeNode(node, &val) {\n\t\t\treturn nil\n\t\t}\n\t\treturn val\n\t}\n\treturn nil\n}\n\nfunc environment(yml yaml.Node) map[string]string {\n\tenv := make(map[string]string)\n\tif yml.Kind == yaml.MappingNode {\n\t\tif !decodeNode(yml, &env) {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn env\n}\n\n// Environment returns string-based key=value map for a job\nfunc (j *Job) Environment() map[string]string {\n\treturn environment(j.Env)\n}\n\n// Matrix decodes RawMatrix YAML node\nfunc (j *Job) Matrix() map[string][]interface{} {\n\tif j.Strategy.RawMatrix.Kind == yaml.MappingNode {\n\t\tvar val map[string][]interface{}\n\t\tif !decodeNode(j.Strategy.RawMatrix, &val) {\n\t\t\treturn nil\n\t\t}\n\t\treturn val\n\t}\n\treturn nil\n}\n\n// GetMatrixes returns the matrix cross product\n// It skips includes and hard fails excludes for non-existing keys\nfunc (j *Job) GetMatrixes() ([]map[string]interface{}, error) {\n\tmatrixes := make([]map[string]interface{}, 0)\n\tif j.Strategy != nil {\n\t\tj.Strategy.FailFast = j.Strategy.GetFailFast()\n\t\tj.Strategy.MaxParallel = j.Strategy.GetMaxParallel()\n\n\t\tif m := j.Matrix(); m != nil {\n\t\t\tincludes := make([]map[string]interface{}, 0)\n\t\t\textraIncludes := make([]map[string]interface{}, 0)\n\t\t\tfor _, v := range m[\"include\"] {\n\t\t\t\tswitch t := v.(type) {\n\t\t\t\tcase []interface{}:\n\t\t\t\t\tfor _, i := range t {\n\t\t\t\t\t\ti := i.(map[string]interface{})\n\t\t\t\t\t\tincludes = append(includes, i)\n\t\t\t\t\t}\n\t\t\t\tcase interface{}:\n\t\t\t\t\tv := v.(map[string]interface{})\n\t\t\t\t\tincludes = append(includes, v)\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete(m, \"include\")\n\n\t\t\texcludes := make([]map[string]interface{}, 0)\n\t\t\tfor _, e := range m[\"exclude\"] {\n\t\t\t\te := e.(map[string]interface{})\n\t\t\t\tfor k := range e {\n\t\t\t\t\tif _, ok := m[k]; ok {\n\t\t\t\t\t\texcludes = append(excludes, e)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We fail completely here because that's what GitHub does for non-existing matrix keys, fail on exclude, silent skip on include\n\t\t\t\t\t\treturn nil, fmt.Errorf(\"the workflow is not valid. Matrix exclude key %q does not match any key within the matrix\", k)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete(m, \"exclude\")\n\n\t\t\tmatrixProduct := common.CartesianProduct(m)\n\t\tMATRIX:\n\t\t\tfor _, matrix := range matrixProduct {\n\t\t\t\tfor _, exclude := range excludes {\n\t\t\t\t\tif commonKeysMatch(matrix, exclude) {\n\t\t\t\t\t\tlog.Debugf(\"Skipping matrix '%v' due to exclude '%v'\", matrix, exclude)\n\t\t\t\t\t\tcontinue MATRIX\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmatrixes = append(matrixes, matrix)\n\t\t\t}\n\t\t\tfor _, include := range includes {\n\t\t\t\tmatched := false\n\t\t\t\tfor _, matrix := range matrixes {\n\t\t\t\t\tif commonKeysMatch2(matrix, include, m) {\n\t\t\t\t\t\tmatched = true\n\t\t\t\t\t\tlog.Debugf(\"Adding include values '%v' to existing entry\", include)\n\t\t\t\t\t\tfor k, v := range include {\n\t\t\t\t\t\t\tmatrix[k] = v\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !matched {\n\t\t\t\t\textraIncludes = append(extraIncludes, include)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor _, include := range extraIncludes {\n\t\t\t\tlog.Debugf(\"Adding include '%v'\", include)\n\t\t\t\tmatrixes = append(matrixes, include)\n\t\t\t}\n\t\t\tif len(matrixes) == 0 {\n\t\t\t\tmatrixes = append(matrixes, make(map[string]interface{}))\n\t\t\t}\n\t\t} else {\n\t\t\tmatrixes = append(matrixes, make(map[string]interface{}))\n\t\t}\n\t} else {\n\t\tmatrixes = append(matrixes, make(map[string]interface{}))\n\t\tlog.Debugf(\"Empty Strategy, matrixes=%v\", matrixes)\n\t}\n\treturn matrixes, nil\n}\n\nfunc commonKeysMatch(a map[string]interface{}, b map[string]interface{}) bool {\n\tfor aKey, aVal := range a {\n\t\tif bVal, ok := b[aKey]; ok && !reflect.DeepEqual(aVal, bVal) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc commonKeysMatch2(a map[string]interface{}, b map[string]interface{}, m map[string][]interface{}) bool {\n\tfor aKey, aVal := range a {\n\t\t_, useKey := m[aKey]\n\t\tif bVal, ok := b[aKey]; useKey && ok && !reflect.DeepEqual(aVal, bVal) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// JobType describes what type of job we are about to run\ntype JobType int\n\nconst (\n\t// JobTypeDefault is all jobs that have a `run` attribute\n\tJobTypeDefault JobType = iota\n\n\t// JobTypeReusableWorkflowLocal is all jobs that have a `uses` that is a local workflow in the .github/workflows directory\n\tJobTypeReusableWorkflowLocal\n\n\t// JobTypeReusableWorkflowRemote is all jobs that have a `uses` that references a workflow file in a github repo\n\tJobTypeReusableWorkflowRemote\n\n\t// JobTypeInvalid represents a job which is not configured correctly\n\tJobTypeInvalid\n)\n\nfunc (j JobType) String() string {\n\tswitch j {\n\tcase JobTypeDefault:\n\t\treturn \"default\"\n\tcase JobTypeReusableWorkflowLocal:\n\t\treturn \"local-reusable-workflow\"\n\tcase JobTypeReusableWorkflowRemote:\n\t\treturn \"remote-reusable-workflow\"\n\t}\n\treturn \"unknown\"\n}\n\n// Type returns the type of the job\nfunc (j *Job) Type() (JobType, error) {\n\tisReusable := j.Uses != \"\"\n\n\tif isReusable {\n\t\tisYaml, _ := regexp.MatchString(`\\.(ya?ml)(?:$|@)`, j.Uses)\n\n\t\tif isYaml {\n\t\t\tisLocalPath := strings.HasPrefix(j.Uses, \"./\")\n\t\t\tisRemotePath, _ := regexp.MatchString(`^[^.](.+?/){2,}.+\\.ya?ml@`, j.Uses)\n\t\t\thasVersion, _ := regexp.MatchString(`\\.ya?ml@`, j.Uses)\n\n\t\t\tif isLocalPath {\n\t\t\t\treturn JobTypeReusableWorkflowLocal, nil\n\t\t\t} else if isRemotePath && hasVersion {\n\t\t\t\treturn JobTypeReusableWorkflowRemote, nil\n\t\t\t}\n\t\t}\n\n\t\treturn JobTypeInvalid, fmt.Errorf(\"`uses` key references invalid workflow path '%s'. Must start with './' if it's a local workflow, or must start with '<org>/<repo>/' and include an '@' if it's a remote workflow\", j.Uses)\n\t}\n\n\treturn JobTypeDefault, nil\n}\n\n// ContainerSpec is the specification of the container to use for the job\ntype ContainerSpec struct {\n\tImage       string            `yaml:\"image\"`\n\tEnv         map[string]string `yaml:\"env\"`\n\tPorts       []string          `yaml:\"ports\"`\n\tVolumes     []string          `yaml:\"volumes\"`\n\tOptions     string            `yaml:\"options\"`\n\tCredentials map[string]string `yaml:\"credentials\"`\n\tEntrypoint  string\n\tArgs        string\n\tName        string\n\tReuse       bool\n}\n\n// Step is the structure of one step in a job\ntype Step struct {\n\tID               string    `yaml:\"id\"`\n\tIf               yaml.Node `yaml:\"if\"`\n\tName             string    `yaml:\"name\"`\n\tUses             string    `yaml:\"uses\"`\n\tRun              string    `yaml:\"run\"`\n\tWorkingDirectory string    `yaml:\"working-directory\"`\n\t// WorkflowShell is the shell really configured in the job, directly at step level or higher in defaults.run.shell\n\tWorkflowShell      string            `yaml:\"-\"`\n\tShell              string            `yaml:\"shell\"`\n\tEnv                yaml.Node         `yaml:\"env\"`\n\tWith               map[string]string `yaml:\"with\"`\n\tRawContinueOnError string            `yaml:\"continue-on-error\"`\n\tTimeoutMinutes     string            `yaml:\"timeout-minutes\"`\n}\n\n// String gets the name of step\nfunc (s *Step) String() string {\n\tif s.Name != \"\" {\n\t\treturn s.Name\n\t} else if s.Uses != \"\" {\n\t\treturn s.Uses\n\t} else if s.Run != \"\" {\n\t\treturn s.Run\n\t}\n\treturn s.ID\n}\n\n// Environment returns string-based key=value map for a step\nfunc (s *Step) Environment() map[string]string {\n\treturn environment(s.Env)\n}\n\n// GetEnv gets the env for a step\nfunc (s *Step) GetEnv() map[string]string {\n\tenv := s.Environment()\n\n\tfor k, v := range s.With {\n\t\tenvKey := regexp.MustCompile(\"[^A-Z0-9-]\").ReplaceAllString(strings.ToUpper(k), \"_\")\n\t\tenvKey = fmt.Sprintf(\"INPUT_%s\", strings.ToUpper(envKey))\n\t\tenv[envKey] = v\n\t}\n\treturn env\n}\n\n// ShellCommand returns the command for the shell\nfunc (s *Step) ShellCommand() string {\n\tshellCommand := \"\"\n\n\t//Reference: https://github.com/actions/runner/blob/8109c962f09d9acc473d92c595ff43afceddb347/src/Runner.Worker/Handlers/ScriptHandlerHelpers.cs#L9-L17\n\tswitch s.Shell {\n\tcase \"\":\n\t\tshellCommand = \"bash -e {0}\"\n\tcase \"bash\":\n\t\tif s.WorkflowShell == \"\" {\n\t\t\tshellCommand = \"bash -e {0}\"\n\t\t} else {\n\t\t\tshellCommand = \"bash --noprofile --norc -e -o pipefail {0}\"\n\t\t}\n\tcase \"pwsh\":\n\t\tshellCommand = \"pwsh -command . '{0}'\"\n\tcase \"python\":\n\t\tshellCommand = \"python {0}\"\n\tcase \"sh\":\n\t\tshellCommand = \"sh -e {0}\"\n\tcase \"cmd\":\n\t\tshellCommand = \"cmd /D /E:ON /V:OFF /S /C \\\"CALL \\\"{0}\\\"\\\"\"\n\tcase \"powershell\":\n\t\tshellCommand = \"powershell -command . '{0}'\"\n\tdefault:\n\t\tshellCommand = s.Shell\n\t}\n\treturn shellCommand\n}\n\n// StepType describes what type of step we are about to run\ntype StepType int\n\nconst (\n\t// StepTypeRun is all steps that have a `run` attribute\n\tStepTypeRun StepType = iota\n\n\t// StepTypeUsesDockerURL is all steps that have a `uses` that is of the form `docker://...`\n\tStepTypeUsesDockerURL\n\n\t// StepTypeUsesActionLocal is all steps that have a `uses` that is a local action in a subdirectory\n\tStepTypeUsesActionLocal\n\n\t// StepTypeUsesActionRemote is all steps that have a `uses` that is a reference to a github repo\n\tStepTypeUsesActionRemote\n\n\t// StepTypeReusableWorkflowLocal is all steps that have a `uses` that is a local workflow in the .github/workflows directory\n\tStepTypeReusableWorkflowLocal\n\n\t// StepTypeReusableWorkflowRemote is all steps that have a `uses` that references a workflow file in a github repo\n\tStepTypeReusableWorkflowRemote\n\n\t// StepTypeInvalid is for steps that have invalid step action\n\tStepTypeInvalid\n)\n\nfunc (s StepType) String() string {\n\tswitch s {\n\tcase StepTypeInvalid:\n\t\treturn \"invalid\"\n\tcase StepTypeRun:\n\t\treturn \"run\"\n\tcase StepTypeUsesActionLocal:\n\t\treturn \"local-action\"\n\tcase StepTypeUsesActionRemote:\n\t\treturn \"remote-action\"\n\tcase StepTypeUsesDockerURL:\n\t\treturn \"docker\"\n\tcase StepTypeReusableWorkflowLocal:\n\t\treturn \"local-reusable-workflow\"\n\tcase StepTypeReusableWorkflowRemote:\n\t\treturn \"remote-reusable-workflow\"\n\t}\n\treturn \"unknown\"\n}\n\n// Type returns the type of the step\nfunc (s *Step) Type() StepType {\n\tif s.Run == \"\" && s.Uses == \"\" {\n\t\treturn StepTypeInvalid\n\t}\n\n\tif s.Run != \"\" {\n\t\tif s.Uses != \"\" {\n\t\t\treturn StepTypeInvalid\n\t\t}\n\t\treturn StepTypeRun\n\t} else if strings.HasPrefix(s.Uses, \"docker://\") {\n\t\treturn StepTypeUsesDockerURL\n\t} else if strings.HasPrefix(s.Uses, \"./.github/workflows\") && (strings.HasSuffix(s.Uses, \".yml\") || strings.HasSuffix(s.Uses, \".yaml\")) {\n\t\treturn StepTypeReusableWorkflowLocal\n\t} else if !strings.HasPrefix(s.Uses, \"./\") && strings.Contains(s.Uses, \".github/workflows\") && (strings.Contains(s.Uses, \".yml@\") || strings.Contains(s.Uses, \".yaml@\")) {\n\t\treturn StepTypeReusableWorkflowRemote\n\t} else if strings.HasPrefix(s.Uses, \"./\") {\n\t\treturn StepTypeUsesActionLocal\n\t}\n\treturn StepTypeUsesActionRemote\n}\n\n// ReadWorkflow returns a list of jobs for a given workflow file reader\nfunc ReadWorkflow(in io.Reader, strict bool) (*Workflow, error) {\n\tif strict {\n\t\tw := new(WorkflowStrict)\n\t\terr := yaml.NewDecoder(in).Decode(w)\n\t\treturn (*Workflow)(w), err\n\t}\n\tw := new(Workflow)\n\terr := yaml.NewDecoder(in).Decode(w)\n\treturn w, err\n}\n\n// GetJob will get a job by name in the workflow\nfunc (w *Workflow) GetJob(jobID string) *Job {\n\tfor id, j := range w.Jobs {\n\t\tif jobID == id {\n\t\t\tif j.Name == \"\" {\n\t\t\t\tj.Name = id\n\t\t\t}\n\t\t\tif j.If.Value == \"\" {\n\t\t\t\tj.If.Value = \"success()\"\n\t\t\t}\n\t\t\treturn j\n\t\t}\n\t}\n\treturn nil\n}\n\n// GetJobIDs will get all the job names in the workflow\nfunc (w *Workflow) GetJobIDs() []string {\n\tids := make([]string, 0)\n\tfor id := range w.Jobs {\n\t\tids = append(ids, id)\n\t}\n\treturn ids\n}\n\nvar OnDecodeNodeError = func(node yaml.Node, out interface{}, err error) {\n\tlog.Fatalf(\"Failed to decode node %v into %T: %v\", node, out, err)\n}\n\nfunc decodeNode(node yaml.Node, out interface{}) bool {\n\tif err := node.Decode(out); err != nil {\n\t\tif OnDecodeNodeError != nil {\n\t\t\tOnDecodeNodeError(node, out, err)\n\t\t}\n\t\treturn false\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "pkg/model/workflow_test.go",
    "content": "package model\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"gopkg.in/yaml.v3\"\n)\n\nfunc TestReadWorkflow_StringEvent(t *testing.T) {\n\tyaml := `\nname: local-action-docker-url\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: ./actions/docker-url\n`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\n\tassert.Len(t, workflow.On(), 1)\n\tassert.Contains(t, workflow.On(), \"push\")\n}\n\nfunc TestReadWorkflow_ListEvent(t *testing.T) {\n\tyaml := `\nname: local-action-docker-url\non: [push, pull_request]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: ./actions/docker-url\n`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\n\tassert.Len(t, workflow.On(), 2)\n\tassert.Contains(t, workflow.On(), \"push\")\n\tassert.Contains(t, workflow.On(), \"pull_request\")\n}\n\nfunc TestReadWorkflow_MapEvent(t *testing.T) {\n\tyaml := `\nname: local-action-docker-url\non:\n  push:\n    branches:\n    - master\n  pull_request:\n    branches:\n    - master\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: ./actions/docker-url\n`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tassert.Len(t, workflow.On(), 2)\n\tassert.Contains(t, workflow.On(), \"push\")\n\tassert.Contains(t, workflow.On(), \"pull_request\")\n}\n\nfunc TestReadWorkflow_RunsOnLabels(t *testing.T) {\n\tyaml := `\nname: local-action-docker-url\n\njobs:\n  test:\n    container: nginx:latest\n    runs-on:\n      labels: ubuntu-latest\n    steps:\n    - uses: ./actions/docker-url`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tassert.Equal(t, workflow.Jobs[\"test\"].RunsOn(), []string{\"ubuntu-latest\"})\n}\n\nfunc TestReadWorkflow_RunsOnLabelsWithGroup(t *testing.T) {\n\tyaml := `\nname: local-action-docker-url\n\njobs:\n  test:\n    container: nginx:latest\n    runs-on:\n      labels: [ubuntu-latest]\n      group: linux\n    steps:\n    - uses: ./actions/docker-url`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tassert.Equal(t, workflow.Jobs[\"test\"].RunsOn(), []string{\"ubuntu-latest\", \"linux\"})\n}\n\nfunc TestReadWorkflow_StringContainer(t *testing.T) {\n\tyaml := `\nname: local-action-docker-url\n\njobs:\n  test:\n    container: nginx:latest\n    runs-on: ubuntu-latest\n    steps:\n    - uses: ./actions/docker-url\n  test2:\n    container:\n      image: nginx:latest\n      env:\n        foo: bar\n    runs-on: ubuntu-latest\n    steps:\n    - uses: ./actions/docker-url\n`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tassert.Len(t, workflow.Jobs, 2)\n\tassert.Contains(t, workflow.Jobs[\"test\"].Container().Image, \"nginx:latest\")\n\tassert.Contains(t, workflow.Jobs[\"test2\"].Container().Image, \"nginx:latest\")\n\tassert.Contains(t, workflow.Jobs[\"test2\"].Container().Env[\"foo\"], \"bar\")\n}\n\nfunc TestReadWorkflow_ObjectContainer(t *testing.T) {\n\tyaml := `\nname: local-action-docker-url\n\njobs:\n  test:\n    container:\n      image: r.example.org/something:latest\n      credentials:\n        username: registry-username\n        password: registry-password\n      env:\n        HOME: /home/user\n      volumes:\n        - my_docker_volume:/volume_mount\n        - /data/my_data\n        - /source/directory:/destination/directory\n    runs-on: ubuntu-latest\n    steps:\n    - uses: ./actions/docker-url\n`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tassert.Len(t, workflow.Jobs, 1)\n\n\tcontainer := workflow.GetJob(\"test\").Container()\n\n\tassert.Contains(t, container.Image, \"r.example.org/something:latest\")\n\tassert.Contains(t, container.Env[\"HOME\"], \"/home/user\")\n\tassert.Contains(t, container.Credentials[\"username\"], \"registry-username\")\n\tassert.Contains(t, container.Credentials[\"password\"], \"registry-password\")\n\tassert.ElementsMatch(t, container.Volumes, []string{\n\t\t\"my_docker_volume:/volume_mount\",\n\t\t\"/data/my_data\",\n\t\t\"/source/directory:/destination/directory\",\n\t})\n}\n\nfunc TestReadWorkflow_JobTypes(t *testing.T) {\n\tyaml := `\nname: invalid job definition\n\njobs:\n  default-job:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo\n  remote-reusable-workflow-yml:\n    uses: remote/repo/some/path/to/workflow.yml@main\n  remote-reusable-workflow-yaml:\n    uses: remote/repo/some/path/to/workflow.yaml@main\n  remote-reusable-workflow-custom-path:\n    uses: remote/repo/path/to/workflow.yml@main\n  local-reusable-workflow-yml:\n    uses: ./some/path/to/workflow.yml\n  local-reusable-workflow-yaml:\n    uses: ./some/path/to/workflow.yaml\n`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tassert.Len(t, workflow.Jobs, 6)\n\n\tjobType, err := workflow.Jobs[\"default-job\"].Type()\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, JobTypeDefault, jobType)\n\n\tjobType, err = workflow.Jobs[\"remote-reusable-workflow-yml\"].Type()\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, JobTypeReusableWorkflowRemote, jobType)\n\n\tjobType, err = workflow.Jobs[\"remote-reusable-workflow-yaml\"].Type()\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, JobTypeReusableWorkflowRemote, jobType)\n\n\tjobType, err = workflow.Jobs[\"remote-reusable-workflow-custom-path\"].Type()\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, JobTypeReusableWorkflowRemote, jobType)\n\n\tjobType, err = workflow.Jobs[\"local-reusable-workflow-yml\"].Type()\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, JobTypeReusableWorkflowLocal, jobType)\n\n\tjobType, err = workflow.Jobs[\"local-reusable-workflow-yaml\"].Type()\n\tassert.Equal(t, nil, err)\n\tassert.Equal(t, JobTypeReusableWorkflowLocal, jobType)\n}\n\nfunc TestReadWorkflow_JobTypes_InvalidPath(t *testing.T) {\n\tyaml := `\nname: invalid job definition\n\njobs:\n  remote-reusable-workflow-missing-version:\n    uses: remote/repo/some/path/to/workflow.yml\n  remote-reusable-workflow-bad-extension:\n    uses: remote/repo/some/path/to/workflow.json\n  local-reusable-workflow-bad-extension:\n    uses: ./some/path/to/workflow.json\n  local-reusable-workflow-bad-path:\n    uses: some/path/to/workflow.yaml\n`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tassert.Len(t, workflow.Jobs, 4)\n\n\tjobType, err := workflow.Jobs[\"remote-reusable-workflow-missing-version\"].Type()\n\tassert.Equal(t, JobTypeInvalid, jobType)\n\tassert.NotEqual(t, nil, err)\n\n\tjobType, err = workflow.Jobs[\"remote-reusable-workflow-bad-extension\"].Type()\n\tassert.Equal(t, JobTypeInvalid, jobType)\n\tassert.NotEqual(t, nil, err)\n\n\tjobType, err = workflow.Jobs[\"local-reusable-workflow-bad-extension\"].Type()\n\tassert.Equal(t, JobTypeInvalid, jobType)\n\tassert.NotEqual(t, nil, err)\n\n\tjobType, err = workflow.Jobs[\"local-reusable-workflow-bad-path\"].Type()\n\tassert.Equal(t, JobTypeInvalid, jobType)\n\tassert.NotEqual(t, nil, err)\n}\n\nfunc TestReadWorkflow_StepsTypes(t *testing.T) {\n\tyaml := `\nname: invalid step definition\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - name: test1\n        uses: actions/checkout@v2\n        run: echo\n      - name: test2\n        run: echo\n      - name: test3\n        uses: actions/checkout@v2\n      - name: test4\n        uses: docker://nginx:latest\n      - name: test5\n        uses: ./local-action\n`\n\n\t_, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.Error(t, err, \"read workflow should fail\")\n}\n\n// See: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idoutputs\nfunc TestReadWorkflow_JobOutputs(t *testing.T) {\n\tyaml := `\nname: job outputs definition\n\njobs:\n  test1:\n    runs-on: ubuntu-latest\n    steps:\n      - id: test1_1\n        run: |\n          echo \"::set-output name=a_key::some-a_value\"\n          echo \"::set-output name=b-key::some-b-value\"\n    outputs:\n      some_a_key: ${{ steps.test1_1.outputs.a_key }}\n      some-b-key: ${{ steps.test1_1.outputs.b-key }}\n\n  test2:\n    runs-on: ubuntu-latest\n    needs:\n      - test1\n    steps:\n      - name: test2_1\n        run: |\n          echo \"${{ needs.test1.outputs.some_a_key }}\"\n          echo \"${{ needs.test1.outputs.some-b-key }}\"\n`\n\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tassert.Len(t, workflow.Jobs, 2)\n\n\tassert.Len(t, workflow.Jobs[\"test1\"].Steps, 1)\n\tassert.Equal(t, StepTypeRun, workflow.Jobs[\"test1\"].Steps[0].Type())\n\tassert.Equal(t, \"test1_1\", workflow.Jobs[\"test1\"].Steps[0].ID)\n\tassert.Len(t, workflow.Jobs[\"test1\"].Outputs, 2)\n\tassert.Contains(t, workflow.Jobs[\"test1\"].Outputs, \"some_a_key\")\n\tassert.Contains(t, workflow.Jobs[\"test1\"].Outputs, \"some-b-key\")\n\tassert.Equal(t, \"${{ steps.test1_1.outputs.a_key }}\", workflow.Jobs[\"test1\"].Outputs[\"some_a_key\"])\n\tassert.Equal(t, \"${{ steps.test1_1.outputs.b-key }}\", workflow.Jobs[\"test1\"].Outputs[\"some-b-key\"])\n}\n\nfunc TestReadWorkflow_Strategy(t *testing.T) {\n\tw, err := NewWorkflowPlanner(\"testdata/strategy/push.yml\", true, false)\n\tassert.NoError(t, err)\n\n\tp, err := w.PlanJob(\"strategy-only-max-parallel\")\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, len(p.Stages), 1)\n\tassert.Equal(t, len(p.Stages[0].Runs), 1)\n\n\twf := p.Stages[0].Runs[0].Workflow\n\n\tjob := wf.Jobs[\"strategy-only-max-parallel\"]\n\tmatrixes, err := job.GetMatrixes()\n\tassert.NoError(t, err)\n\tassert.Equal(t, matrixes, []map[string]interface{}{{}})\n\tassert.Equal(t, job.Matrix(), map[string][]interface{}(nil))\n\tassert.Equal(t, job.Strategy.MaxParallel, 2)\n\tassert.Equal(t, job.Strategy.FailFast, true)\n\n\tjob = wf.Jobs[\"strategy-only-fail-fast\"]\n\tmatrixes, err = job.GetMatrixes()\n\tassert.NoError(t, err)\n\tassert.Equal(t, matrixes, []map[string]interface{}{{}})\n\tassert.Equal(t, job.Matrix(), map[string][]interface{}(nil))\n\tassert.Equal(t, job.Strategy.MaxParallel, 4)\n\tassert.Equal(t, job.Strategy.FailFast, false)\n\n\tjob = wf.Jobs[\"strategy-no-matrix\"]\n\tmatrixes, err = job.GetMatrixes()\n\tassert.NoError(t, err)\n\tassert.Equal(t, matrixes, []map[string]interface{}{{}})\n\tassert.Equal(t, job.Matrix(), map[string][]interface{}(nil))\n\tassert.Equal(t, job.Strategy.MaxParallel, 2)\n\tassert.Equal(t, job.Strategy.FailFast, false)\n\n\tjob = wf.Jobs[\"strategy-all\"]\n\tmatrixes, err = job.GetMatrixes()\n\tassert.NoError(t, err)\n\tassert.Equal(t, matrixes,\n\t\t[]map[string]interface{}{\n\t\t\t{\"datacenter\": \"site-c\", \"node-version\": \"14.x\", \"site\": \"staging\", \"php-version\": 5.4},\n\t\t\t{\"datacenter\": \"site-c\", \"node-version\": \"16.x\", \"site\": \"staging\", \"php-version\": 5.4},\n\t\t\t{\"datacenter\": \"site-d\", \"node-version\": \"16.x\", \"site\": \"staging\", \"php-version\": 5.4},\n\t\t\t{\"datacenter\": \"site-a\", \"node-version\": \"10.x\", \"site\": \"prod\"},\n\t\t\t{\"datacenter\": \"site-b\", \"node-version\": \"12.x\", \"site\": \"dev\"},\n\t\t},\n\t)\n\tassert.Equal(t, job.Matrix(),\n\t\tmap[string][]interface{}{\n\t\t\t\"datacenter\": {\"site-c\", \"site-d\"},\n\t\t\t\"exclude\": {\n\t\t\t\tmap[string]interface{}{\"datacenter\": \"site-d\", \"node-version\": \"14.x\", \"site\": \"staging\"},\n\t\t\t},\n\t\t\t\"include\": {\n\t\t\t\tmap[string]interface{}{\"php-version\": 5.4},\n\t\t\t\tmap[string]interface{}{\"datacenter\": \"site-a\", \"node-version\": \"10.x\", \"site\": \"prod\"},\n\t\t\t\tmap[string]interface{}{\"datacenter\": \"site-b\", \"node-version\": \"12.x\", \"site\": \"dev\"},\n\t\t\t},\n\t\t\t\"node-version\": {\"14.x\", \"16.x\"},\n\t\t\t\"site\":         {\"staging\"},\n\t\t},\n\t)\n\tassert.Equal(t, job.Strategy.MaxParallel, 2)\n\tassert.Equal(t, job.Strategy.FailFast, false)\n}\n\nfunc TestMatrixOnlyIncludes(t *testing.T) {\n\tmatrix := map[string][]interface{}{\n\t\t\"include\": []interface{}{\n\t\t\tmap[string]interface{}{\"a\": \"1\", \"b\": \"2\"},\n\t\t\tmap[string]interface{}{\"a\": \"3\", \"b\": \"4\"},\n\t\t},\n\t}\n\trN := yaml.Node{}\n\terr := rN.Encode(matrix)\n\trequire.NoError(t, err, \"encoding matrix should succeed\")\n\tjob := &Job{\n\t\tStrategy: &Strategy{\n\t\t\tRawMatrix: rN,\n\t\t},\n\t}\n\tassert.Equal(t, job.Matrix(), matrix)\n\tmatrixes, err := job.GetMatrixes()\n\trequire.NoError(t, err)\n\tassert.Equal(t, matrixes,\n\t\t[]map[string]interface{}{\n\t\t\t{\"a\": \"1\", \"b\": \"2\"},\n\t\t\t{\"a\": \"3\", \"b\": \"4\"},\n\t\t},\n\t)\n}\n\nfunc TestStep_ShellCommand(t *testing.T) {\n\ttests := []struct {\n\t\tshell         string\n\t\tworkflowShell string\n\t\twant          string\n\t}{\n\t\t{\"pwsh -v '. {0}'\", \"\", \"pwsh -v '. {0}'\"},\n\t\t{\"pwsh\", \"\", \"pwsh -command . '{0}'\"},\n\t\t{\"powershell\", \"\", \"powershell -command . '{0}'\"},\n\t\t{\"bash\", \"\", \"bash -e {0}\"},\n\t\t{\"bash\", \"bash\", \"bash --noprofile --norc -e -o pipefail {0}\"},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.shell, func(t *testing.T) {\n\t\t\tgot := (&Step{Shell: tt.shell, WorkflowShell: tt.workflowShell}).ShellCommand()\n\t\t\tassert.Equal(t, got, tt.want)\n\t\t})\n\t}\n}\n\nfunc TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {\n\tyaml := `\n    name: local-action-docker-url\n    `\n\tworkflow, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tworkflowDispatch := workflow.WorkflowDispatchConfig()\n\tassert.Nil(t, workflowDispatch)\n\n\tyaml = `\n    name: local-action-docker-url\n    on: push\n    `\n\tworkflow, err = ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tworkflowDispatch = workflow.WorkflowDispatchConfig()\n\tassert.Nil(t, workflowDispatch)\n\n\tyaml = `\n    name: local-action-docker-url\n    on: workflow_dispatch\n    `\n\tworkflow, err = ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tworkflowDispatch = workflow.WorkflowDispatchConfig()\n\tassert.NotNil(t, workflowDispatch)\n\tassert.Nil(t, workflowDispatch.Inputs)\n\n\tyaml = `\n    name: local-action-docker-url\n    on: [push, pull_request]\n    `\n\tworkflow, err = ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tworkflowDispatch = workflow.WorkflowDispatchConfig()\n\tassert.Nil(t, workflowDispatch)\n\n\tyaml = `\n    name: local-action-docker-url\n    on: [push, workflow_dispatch]\n    `\n\tworkflow, err = ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tworkflowDispatch = workflow.WorkflowDispatchConfig()\n\tassert.NotNil(t, workflowDispatch)\n\tassert.Nil(t, workflowDispatch.Inputs)\n\n\tyaml = `\n    name: local-action-docker-url\n    on:\n        - push\n        - workflow_dispatch\n    `\n\tworkflow, err = ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tworkflowDispatch = workflow.WorkflowDispatchConfig()\n\tassert.NotNil(t, workflowDispatch)\n\tassert.Nil(t, workflowDispatch.Inputs)\n\n\tyaml = `\n    name: local-action-docker-url\n    on:\n        push:\n        pull_request:\n    `\n\tworkflow, err = ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tworkflowDispatch = workflow.WorkflowDispatchConfig()\n\tassert.Nil(t, workflowDispatch)\n\n\tyaml = `\n    name: local-action-docker-url\n    on:\n        push:\n        pull_request:\n        workflow_dispatch:\n            inputs:\n                logLevel:\n                    description: 'Log level'\n                    required: true\n                    default: 'warning'\n                    type: choice\n                    options:\n                    - info\n                    - warning\n                    - debug\n    `\n\tworkflow, err = ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\tworkflowDispatch = workflow.WorkflowDispatchConfig()\n\tassert.NotNil(t, workflowDispatch)\n\tassert.Equal(t, WorkflowDispatchInput{\n\t\tDefault:     \"warning\",\n\t\tDescription: \"Log level\",\n\t\tOptions: []string{\n\t\t\t\"info\",\n\t\t\t\"warning\",\n\t\t\t\"debug\",\n\t\t},\n\t\tRequired: true,\n\t\tType:     \"choice\",\n\t}, workflowDispatch.Inputs[\"logLevel\"])\n}\n\nfunc TestReadWorkflow_InvalidStringEvent(t *testing.T) {\n\tyaml := `\nname: local-action-docker-url\non: push2\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: ./actions/docker-url\n`\n\n\t_, err := ReadWorkflow(strings.NewReader(yaml), true)\n\tassert.Error(t, err, \"read workflow should succeed\")\n}\n\nfunc TestReadWorkflow_AnchorStrict(t *testing.T) {\n\tyaml := `\non: push\n\njobs:\n  test:\n    runs-on: &runner ubuntu-latest\n    steps:\n    - uses: &checkout actions/checkout@v5\n  test2:\n    runs-on: *runner\n    steps:\n    - uses: *checkout\n`\n\n\tw, err := ReadWorkflow(strings.NewReader(yaml), true)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\n\tfor _, job := range w.Jobs {\n\t\tassert.Equal(t, []string{\"ubuntu-latest\"}, job.RunsOn())\n\t\tassert.Equal(t, \"actions/checkout@v5\", job.Steps[0].Uses)\n\t}\n}\n\nfunc TestReadWorkflow_Anchor(t *testing.T) {\n\tyaml := `\n\njobs:\n  test:\n    runs-on: &runner ubuntu-latest\n    steps:\n    - uses: &checkout actions/checkout@v5\n  test2: &job\n    runs-on: *runner\n    steps:\n    - uses: *checkout\n    - run: echo $TRIGGER\n      env:\n        TRIGGER: &trigger push\n  test3: *job\non: push #*trigger\n`\n\n\tw, err := ReadWorkflow(strings.NewReader(yaml), false)\n\tassert.NoError(t, err, \"read workflow should succeed\")\n\n\tfor _, job := range w.Jobs {\n\t\tassert.Equal(t, []string{\"ubuntu-latest\"}, job.RunsOn())\n\t\tassert.Equal(t, \"actions/checkout@v5\", job.Steps[0].Uses)\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/action.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"embed\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/kballard/go-shellquote\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype actionStep interface {\n\tstep\n\n\tgetActionModel() *model.Action\n\tgetCompositeRunContext(context.Context) *RunContext\n\tgetCompositeSteps() *compositeSteps\n}\n\ntype readAction func(ctx context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error)\n\ntype actionYamlReader func(filename string) (io.Reader, io.Closer, error)\n\ntype fileWriter func(filename string, data []byte, perm fs.FileMode) error\n\ntype runAction func(step actionStep, actionDir string, remoteAction *remoteAction) common.Executor\n\n//go:embed res/trampoline.js\nvar trampoline embed.FS\n\nfunc readActionImpl(ctx context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {\n\tlogger := common.Logger(ctx)\n\tallErrors := []error{}\n\taddError := func(fileName string, err error) {\n\t\tif err != nil {\n\t\t\tallErrors = append(allErrors, fmt.Errorf(\"failed to read '%s' from action '%s' with path '%s' of step: %w\", fileName, step.String(), actionPath, err))\n\t\t} else {\n\t\t\t// One successful read, clear error state\n\t\t\tallErrors = nil\n\t\t}\n\t}\n\treader, closer, err := readFile(\"action.yml\")\n\taddError(\"action.yml\", err)\n\tif os.IsNotExist(err) {\n\t\treader, closer, err = readFile(\"action.yaml\")\n\t\taddError(\"action.yaml\", err)\n\t\tif os.IsNotExist(err) {\n\t\t\t_, closer, err := readFile(\"Dockerfile\")\n\t\t\taddError(\"Dockerfile\", err)\n\t\t\tif err == nil {\n\t\t\t\tcloser.Close()\n\t\t\t\taction := &model.Action{\n\t\t\t\t\tName: \"(Synthetic)\",\n\t\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\t\tUsing: \"docker\",\n\t\t\t\t\t\tImage: \"Dockerfile\",\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tlogger.Debugf(\"Using synthetic action %v for Dockerfile\", action)\n\t\t\t\treturn action, nil\n\t\t\t}\n\t\t\tif step.With != nil {\n\t\t\t\tif val, ok := step.With[\"args\"]; ok {\n\t\t\t\t\tvar b []byte\n\t\t\t\t\tif b, err = trampoline.ReadFile(\"res/trampoline.js\"); err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\terr2 := writeFile(filepath.Join(actionDir, actionPath, \"trampoline.js\"), b, 0o400)\n\t\t\t\t\tif err2 != nil {\n\t\t\t\t\t\treturn nil, err2\n\t\t\t\t\t}\n\t\t\t\t\taction := &model.Action{\n\t\t\t\t\t\tName: \"(Synthetic)\",\n\t\t\t\t\t\tInputs: map[string]model.Input{\n\t\t\t\t\t\t\t\"cwd\": {\n\t\t\t\t\t\t\t\tDescription: \"(Actual working directory)\",\n\t\t\t\t\t\t\t\tRequired:    false,\n\t\t\t\t\t\t\t\tDefault:     filepath.Join(actionDir, actionPath),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"command\": {\n\t\t\t\t\t\t\t\tDescription: \"(Actual program)\",\n\t\t\t\t\t\t\t\tRequired:    false,\n\t\t\t\t\t\t\t\tDefault:     val,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\t\t\tUsing: \"node12\",\n\t\t\t\t\t\t\tMain:  \"trampoline.js\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t\tlogger.Debugf(\"Using synthetic action %v\", action)\n\t\t\t\t\treturn action, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif allErrors != nil {\n\t\treturn nil, errors.Join(allErrors...)\n\t}\n\tdefer closer.Close()\n\n\taction, err := model.ReadAction(reader)\n\tlogger.Debugf(\"Read action %v from '%s'\", action, \"Unknown\")\n\treturn action, err\n}\n\nfunc maybeCopyToActionDir(ctx context.Context, step actionStep, actionDir string, actionPath string, containerActionDir string) error {\n\tlogger := common.Logger(ctx)\n\trc := step.getRunContext()\n\tstepModel := step.getStepModel()\n\n\tif stepModel.Type() != model.StepTypeUsesActionRemote {\n\t\treturn nil\n\t}\n\n\tvar containerActionDirCopy string\n\tcontainerActionDirCopy = strings.TrimSuffix(containerActionDir, actionPath)\n\tlogger.Debug(containerActionDirCopy)\n\n\tif !strings.HasSuffix(containerActionDirCopy, `/`) {\n\t\tcontainerActionDirCopy += `/`\n\t}\n\n\tif rc.Config != nil && rc.Config.ActionCache != nil {\n\t\traction := step.(*stepActionRemote)\n\t\tta, err := rc.Config.ActionCache.GetTarArchive(ctx, raction.cacheDir, raction.resolvedSha, \"\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer ta.Close()\n\t\treturn rc.JobContainer.CopyTarStream(ctx, containerActionDirCopy, ta)\n\t}\n\n\tif err := removeGitIgnore(ctx, actionDir); err != nil {\n\t\treturn err\n\t}\n\n\treturn rc.JobContainer.CopyDir(containerActionDirCopy, actionDir+\"/\", rc.Config.UseGitIgnore)(ctx)\n}\n\nfunc runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction) common.Executor {\n\trc := step.getRunContext()\n\tstepModel := step.getStepModel()\n\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tactionPath := \"\"\n\t\tif remoteAction != nil && remoteAction.Path != \"\" {\n\t\t\tactionPath = remoteAction.Path\n\t\t}\n\n\t\taction := step.getActionModel()\n\t\tlogger.Debugf(\"About to run action %v\", action)\n\n\t\terr := setupActionEnv(ctx, step, remoteAction)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tactionLocation := path.Join(actionDir, actionPath)\n\t\tactionName, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)\n\n\t\tlogger.Debugf(\"type=%v actionDir=%s actionPath=%s workdir=%s actionCacheDir=%s actionName=%s containerActionDir=%s\", stepModel.Type(), actionDir, actionPath, rc.Config.Workdir, rc.ActionCacheDir(), actionName, containerActionDir)\n\n\t\tx := action.Runs.Using\n\t\tswitch {\n\t\tcase x.IsNode():\n\t\t\tif err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontainerArgs := []string{rc.GetNodeToolFullPath(ctx), path.Join(containerActionDir, action.Runs.Main)}\n\t\t\tlogger.Debugf(\"executing remote job container: %s\", containerArgs)\n\n\t\t\trc.ApplyExtraPath(ctx, step.getEnv())\n\n\t\t\treturn rc.execJobContainer(containerArgs, *step.getEnv(), \"\", \"\")(ctx)\n\t\tcase x.IsDocker():\n\t\t\tif remoteAction == nil {\n\t\t\t\tactionDir = \"\"\n\t\t\t\tactionPath = containerActionDir\n\t\t\t}\n\t\t\treturn execAsDocker(ctx, step, actionName, actionDir, actionPath, remoteAction == nil, \"entrypoint\")\n\t\tcase x.IsComposite():\n\t\t\tif err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn execAsComposite(step)(ctx)\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"The runs.using key must be one of: %v, got %s\", []string{\n\t\t\t\tmodel.ActionRunsUsingDocker,\n\t\t\t\tmodel.ActionRunsUsingNode12,\n\t\t\t\tmodel.ActionRunsUsingNode16,\n\t\t\t\tmodel.ActionRunsUsingNode20,\n\t\t\t\tmodel.ActionRunsUsingNode24,\n\t\t\t\tmodel.ActionRunsUsingComposite,\n\t\t\t}, action.Runs.Using)\n\t\t}\n\t}\n}\n\nfunc setupActionEnv(ctx context.Context, step actionStep, _ *remoteAction) error {\n\trc := step.getRunContext()\n\n\t// A few fields in the environment (e.g. GITHUB_ACTION_REPOSITORY)\n\t// are dependent on the action. That means we can complete the\n\t// setup only after resolving the whole action model and cloning\n\t// the action\n\trc.withGithubEnv(ctx, step.getGithubContext(ctx), *step.getEnv())\n\tpopulateEnvsFromSavedState(step.getEnv(), step, rc)\n\tpopulateEnvsFromInput(ctx, step.getEnv(), step.getActionModel(), rc)\n\n\treturn nil\n}\n\n// https://github.com/nektos/act/issues/228#issuecomment-629709055\n// files in .gitignore are not copied in a Docker container\n// this causes issues with actions that ignore other important resources\n// such as `node_modules` for example\nfunc removeGitIgnore(ctx context.Context, directory string) error {\n\tgitIgnorePath := path.Join(directory, \".gitignore\")\n\tif _, err := os.Stat(gitIgnorePath); err == nil {\n\t\t// .gitignore exists\n\t\tcommon.Logger(ctx).Debugf(\"Removing %s before docker cp\", gitIgnorePath)\n\t\terr := os.Remove(gitIgnorePath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// TODO: break out parts of function to reduce complexicity\n//\n//nolint:gocyclo\nfunc execAsDocker(ctx context.Context, step actionStep, actionName, basedir, subpath string, localAction bool, entrypointType string) error {\n\tlogger := common.Logger(ctx)\n\trc := step.getRunContext()\n\taction := step.getActionModel()\n\n\tvar prepImage common.Executor\n\tvar image string\n\tforcePull := false\n\tif strings.HasPrefix(action.Runs.Image, \"docker://\") {\n\t\timage = strings.TrimPrefix(action.Runs.Image, \"docker://\")\n\t\t// Apply forcePull only for prebuild docker images\n\t\tforcePull = rc.Config.ForcePull\n\t} else {\n\t\t// \"-dockeraction\" enshures that \"./\", \"./test \" won't get converted to \"act-:latest\", \"act-test-:latest\" which are invalid docker image names\n\t\timage = fmt.Sprintf(\"%s-dockeraction:%s\", regexp.MustCompile(\"[^a-zA-Z0-9]\").ReplaceAllString(actionName, \"-\"), \"latest\")\n\t\timage = fmt.Sprintf(\"act-%s\", strings.TrimLeft(image, \"-\"))\n\t\timage = strings.ToLower(image)\n\t\tcontextDir, fileName := path.Split(path.Join(subpath, action.Runs.Image))\n\n\t\tanyArchExists, err := container.ImageExistsLocally(ctx, image, \"any\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcorrectArchExists, err := container.ImageExistsLocally(ctx, image, rc.Config.ContainerArchitecture)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif anyArchExists && !correctArchExists {\n\t\t\twasRemoved, err := container.RemoveImage(ctx, image, true, true)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif !wasRemoved {\n\t\t\t\treturn fmt.Errorf(\"failed to remove image '%s'\", image)\n\t\t\t}\n\t\t}\n\n\t\tif !correctArchExists || rc.Config.ForceRebuild {\n\t\t\tlogger.Debugf(\"image '%s' for architecture '%s' will be built from context '%s\", image, rc.Config.ContainerArchitecture, contextDir)\n\t\t\tvar buildContext io.ReadCloser\n\t\t\tif localAction {\n\t\t\t\tbuildContext, err = rc.JobContainer.GetContainerArchive(ctx, contextDir+\"/.\")\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tdefer buildContext.Close()\n\t\t\t} else if rc.Config.ActionCache != nil {\n\t\t\t\trstep := step.(*stepActionRemote)\n\t\t\t\tbuildContext, err = rc.Config.ActionCache.GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, contextDir)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tdefer buildContext.Close()\n\t\t\t}\n\t\t\tprepImage = container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{\n\t\t\t\tContextDir:   filepath.Join(basedir, contextDir),\n\t\t\t\tDockerfile:   fileName,\n\t\t\t\tImageTag:     image,\n\t\t\t\tBuildContext: buildContext,\n\t\t\t\tPlatform:     rc.Config.ContainerArchitecture,\n\t\t\t})\n\t\t} else {\n\t\t\tlogger.Debugf(\"image '%s' for architecture '%s' already exists\", image, rc.Config.ContainerArchitecture)\n\t\t}\n\t}\n\teval := rc.NewStepExpressionEvaluator(ctx, step)\n\tcmd, err := shellquote.Split(eval.Interpolate(ctx, step.getStepModel().With[\"args\"]))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(cmd) == 0 {\n\t\tcmd = action.Runs.Args\n\t\tevalDockerArgs(ctx, step, action, &cmd)\n\t}\n\n\tentrypoint := strings.Fields(eval.Interpolate(ctx, step.getStepModel().With[entrypointType]))\n\tif len(entrypoint) == 0 {\n\t\tif entrypointType == \"pre-entrypoint\" && action.Runs.PreEntrypoint != \"\" {\n\t\t\tentrypoint, err = shellquote.Split(action.Runs.PreEntrypoint)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else if entrypointType == \"entrypoint\" && action.Runs.Entrypoint != \"\" {\n\t\t\tentrypoint, err = shellquote.Split(action.Runs.Entrypoint)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else if entrypointType == \"post-entrypoint\" && action.Runs.PostEntrypoint != \"\" {\n\t\t\tentrypoint, err = shellquote.Split(action.Runs.PostEntrypoint)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tentrypoint = nil\n\t\t}\n\t}\n\tstepContainer := newStepContainer(ctx, step, image, cmd, entrypoint)\n\treturn common.NewPipelineExecutor(\n\t\tprepImage,\n\t\tstepContainer.Pull(forcePull),\n\t\tstepContainer.Remove().IfBool(!rc.Config.ReuseContainers),\n\t\tstepContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),\n\t\tstepContainer.Start(true),\n\t).Finally(\n\t\tstepContainer.Remove().IfBool(!rc.Config.ReuseContainers),\n\t).Finally(stepContainer.Close())(ctx)\n}\n\nfunc evalDockerArgs(ctx context.Context, step step, action *model.Action, cmd *[]string) {\n\trc := step.getRunContext()\n\tstepModel := step.getStepModel()\n\n\tinputs := make(map[string]string)\n\teval := rc.NewExpressionEvaluator(ctx)\n\t// Set Defaults\n\tfor k, input := range action.Inputs {\n\t\tinputs[k] = eval.Interpolate(ctx, input.Default)\n\t}\n\tif stepModel.With != nil {\n\t\tfor k, v := range stepModel.With {\n\t\t\tinputs[k] = eval.Interpolate(ctx, v)\n\t\t}\n\t}\n\tmergeIntoMap(step, step.getEnv(), inputs)\n\n\tstepEE := rc.NewStepExpressionEvaluator(ctx, step)\n\tfor i, v := range *cmd {\n\t\t(*cmd)[i] = stepEE.Interpolate(ctx, v)\n\t}\n\tmergeIntoMap(step, step.getEnv(), action.Runs.Env)\n\n\tee := rc.NewStepExpressionEvaluator(ctx, step)\n\tfor k, v := range *step.getEnv() {\n\t\t(*step.getEnv())[k] = ee.Interpolate(ctx, v)\n\t}\n}\n\nfunc newStepContainer(ctx context.Context, step step, image string, cmd []string, entrypoint []string) container.Container {\n\trc := step.getRunContext()\n\tstepModel := step.getStepModel()\n\trawLogger := common.Logger(ctx).WithField(\"raw_output\", true)\n\tlogWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool {\n\t\tif rc.Config.LogOutput {\n\t\t\trawLogger.Infof(\"%s\", s)\n\t\t} else {\n\t\t\trawLogger.Debugf(\"%s\", s)\n\t\t}\n\t\treturn true\n\t})\n\tenvList := make([]string, 0)\n\tfor k, v := range *step.getEnv() {\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", k, v))\n\t}\n\n\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_TOOL_CACHE\", \"/opt/hostedtoolcache\"))\n\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_OS\", \"Linux\"))\n\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_ARCH\", container.RunnerArch(ctx)))\n\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_TEMP\", \"/tmp\"))\n\n\tbinds, mounts := rc.GetBindsAndMounts()\n\tnetworkMode := fmt.Sprintf(\"container:%s\", rc.jobContainerName())\n\tvar workdir string\n\tif rc.IsHostEnv(ctx) {\n\t\tnetworkMode = \"default\"\n\t\text := container.LinuxContainerEnvironmentExtensions{}\n\t\tworkdir = ext.ToContainerPath(rc.Config.Workdir)\n\t} else {\n\t\tworkdir = rc.JobContainer.ToContainerPath(rc.Config.Workdir)\n\t}\n\tstepContainer := container.NewContainer(&container.NewContainerInput{\n\t\tCmd:         cmd,\n\t\tEntrypoint:  entrypoint,\n\t\tWorkingDir:  workdir,\n\t\tImage:       image,\n\t\tUsername:    rc.Config.Secrets[\"DOCKER_USERNAME\"],\n\t\tPassword:    rc.Config.Secrets[\"DOCKER_PASSWORD\"],\n\t\tName:        createContainerName(rc.jobContainerName(), stepModel.ID),\n\t\tEnv:         envList,\n\t\tMounts:      mounts,\n\t\tNetworkMode: networkMode,\n\t\tBinds:       binds,\n\t\tStdout:      logWriter,\n\t\tStderr:      logWriter,\n\t\tPrivileged:  rc.Config.Privileged,\n\t\tUsernsMode:  rc.Config.UsernsMode,\n\t\tPlatform:    rc.Config.ContainerArchitecture,\n\t\tOptions:     rc.Config.ContainerOptions,\n\t})\n\treturn stepContainer\n}\n\nfunc populateEnvsFromSavedState(env *map[string]string, step actionStep, rc *RunContext) {\n\tstate, ok := rc.IntraActionState[step.getStepModel().ID]\n\tif ok {\n\t\tfor name, value := range state {\n\t\t\tenvName := fmt.Sprintf(\"STATE_%s\", name)\n\t\t\t(*env)[envName] = value\n\t\t}\n\t}\n}\n\nfunc populateEnvsFromInput(ctx context.Context, env *map[string]string, action *model.Action, rc *RunContext) {\n\teval := rc.NewExpressionEvaluator(ctx)\n\tfor inputID, input := range action.Inputs {\n\t\tenvKey := regexp.MustCompile(\"[^A-Z0-9-]\").ReplaceAllString(strings.ToUpper(inputID), \"_\")\n\t\tenvKey = fmt.Sprintf(\"INPUT_%s\", envKey)\n\t\tif _, ok := (*env)[envKey]; !ok {\n\t\t\t(*env)[envKey] = eval.Interpolate(ctx, input.Default)\n\t\t}\n\t}\n}\n\nfunc getContainerActionPaths(step *model.Step, actionDir string, rc *RunContext) (string, string) {\n\tactionName := \"\"\n\tcontainerActionDir := \".\"\n\tif step.Type() != model.StepTypeUsesActionRemote {\n\t\tactionName = getOsSafeRelativePath(actionDir, rc.Config.Workdir)\n\t\tcontainerActionDir = rc.JobContainer.ToContainerPath(rc.Config.Workdir) + \"/\" + actionName\n\t\tactionName = \"./\" + actionName\n\t} else if step.Type() == model.StepTypeUsesActionRemote {\n\t\tactionName = getOsSafeRelativePath(actionDir, rc.ActionCacheDir())\n\t\tcontainerActionDir = rc.JobContainer.GetActPath() + \"/actions/\" + actionName\n\t}\n\n\tif actionName == \"\" {\n\t\tactionName = filepath.Base(actionDir)\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\tactionName = strings.ReplaceAll(actionName, \"\\\\\", \"/\")\n\t\t}\n\t}\n\treturn actionName, containerActionDir\n}\n\nfunc getOsSafeRelativePath(s, prefix string) string {\n\tactionName := strings.TrimPrefix(s, prefix)\n\tif runtime.GOOS == \"windows\" {\n\t\tactionName = strings.ReplaceAll(actionName, \"\\\\\", \"/\")\n\t}\n\tactionName = strings.TrimPrefix(actionName, \"/\")\n\n\treturn actionName\n}\n\nfunc shouldRunPreStep(step actionStep) common.Conditional {\n\treturn func(ctx context.Context) bool {\n\t\tlog := common.Logger(ctx)\n\n\t\tif step.getActionModel() == nil {\n\t\t\tlog.Debugf(\"skip pre step for '%s': no action model available\", step.getStepModel())\n\t\t\treturn false\n\t\t}\n\n\t\treturn true\n\t}\n}\n\nfunc hasPreStep(step actionStep) common.Conditional {\n\treturn func(_ context.Context) bool {\n\t\taction := step.getActionModel()\n\t\treturn action.Runs.Using.IsComposite() ||\n\t\t\t(action.Runs.Using.IsNode() &&\n\t\t\t\taction.Runs.Pre != \"\") ||\n\t\t\t(action.Runs.Using.IsDocker() &&\n\t\t\t\taction.Runs.PreEntrypoint != \"\")\n\t}\n}\n\nfunc runPreStep(step actionStep) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tlogger.Debugf(\"run pre step for '%s'\", step.getStepModel())\n\n\t\trc := step.getRunContext()\n\t\tstepModel := step.getStepModel()\n\t\taction := step.getActionModel()\n\n\t\t// defaults in pre steps were missing, however provided inputs are available\n\t\tpopulateEnvsFromInput(ctx, step.getEnv(), action, rc)\n\n\t\t// todo: refactor into step\n\t\tvar actionDir string\n\t\tvar actionPath string\n\t\tvar remoteAction *stepActionRemote\n\t\tif remote, ok := step.(*stepActionRemote); ok {\n\t\t\tactionPath = newRemoteAction(stepModel.Uses).Path\n\t\t\tactionDir = fmt.Sprintf(\"%s/%s\", rc.ActionCacheDir(), safeFilename(stepModel.Uses))\n\t\t\tremoteAction = remote\n\t\t} else {\n\t\t\tactionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)\n\t\t\tactionPath = \"\"\n\t\t}\n\n\t\tactionLocation := \"\"\n\t\tif actionPath != \"\" {\n\t\t\tactionLocation = path.Join(actionDir, actionPath)\n\t\t} else {\n\t\t\tactionLocation = actionDir\n\t\t}\n\n\t\tactionName, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)\n\n\t\tx := action.Runs.Using\n\t\tswitch {\n\t\tcase x.IsNode():\n\t\t\tif err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tcontainerArgs := []string{rc.GetNodeToolFullPath(ctx), path.Join(containerActionDir, action.Runs.Pre)}\n\t\t\tlogger.Debugf(\"executing remote job container: %s\", containerArgs)\n\n\t\t\trc.ApplyExtraPath(ctx, step.getEnv())\n\n\t\t\treturn rc.execJobContainer(containerArgs, *step.getEnv(), \"\", \"\")(ctx)\n\n\t\tcase x.IsDocker():\n\t\t\tif remoteAction == nil {\n\t\t\t\tactionDir = \"\"\n\t\t\t\tactionPath = containerActionDir\n\t\t\t}\n\t\t\treturn execAsDocker(ctx, step, actionName, actionDir, actionPath, remoteAction == nil, \"pre-entrypoint\")\n\n\t\tcase x.IsComposite():\n\t\t\tif step.getCompositeSteps() == nil {\n\t\t\t\tstep.getCompositeRunContext(ctx)\n\t\t\t}\n\n\t\t\tif steps := step.getCompositeSteps(); steps != nil && steps.pre != nil {\n\t\t\t\treturn steps.pre(ctx)\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"missing steps in composite action\")\n\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\nfunc shouldRunPostStep(step actionStep) common.Conditional {\n\treturn func(ctx context.Context) bool {\n\t\tlog := common.Logger(ctx)\n\t\tstepResults := step.getRunContext().getStepsContext()\n\t\tstepResult := stepResults[step.getStepModel().ID]\n\n\t\tif stepResult == nil {\n\t\t\tlog.WithField(\"stepResult\", model.StepStatusSkipped).Debugf(\"skipping post step for '%s'; step was not executed\", step.getStepModel())\n\t\t\treturn false\n\t\t}\n\n\t\tif stepResult.Conclusion == model.StepStatusSkipped {\n\t\t\tlog.WithField(\"stepResult\", model.StepStatusSkipped).Debugf(\"skipping post step for '%s'; main step was skipped\", step.getStepModel())\n\t\t\treturn false\n\t\t}\n\n\t\tif step.getActionModel() == nil {\n\t\t\tlog.WithField(\"stepResult\", model.StepStatusSkipped).Debugf(\"skipping post step for '%s': no action model available\", step.getStepModel())\n\t\t\treturn false\n\t\t}\n\n\t\treturn true\n\t}\n}\n\nfunc hasPostStep(step actionStep) common.Conditional {\n\treturn func(_ context.Context) bool {\n\t\taction := step.getActionModel()\n\t\treturn action.Runs.Using.IsComposite() ||\n\t\t\t(action.Runs.Using.IsNode() &&\n\t\t\t\taction.Runs.Post != \"\") ||\n\t\t\t(action.Runs.Using.IsDocker() &&\n\t\t\t\taction.Runs.PostEntrypoint != \"\")\n\t}\n}\n\nfunc runPostStep(step actionStep) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tlogger.Debugf(\"run post step for '%s'\", step.getStepModel())\n\n\t\trc := step.getRunContext()\n\t\tstepModel := step.getStepModel()\n\t\taction := step.getActionModel()\n\n\t\t// todo: refactor into step\n\t\tvar actionDir string\n\t\tvar actionPath string\n\t\tvar remoteAction *stepActionRemote\n\t\tif remote, ok := step.(*stepActionRemote); ok {\n\t\t\tactionPath = newRemoteAction(stepModel.Uses).Path\n\t\t\tactionDir = fmt.Sprintf(\"%s/%s\", rc.ActionCacheDir(), safeFilename(stepModel.Uses))\n\t\t\tremoteAction = remote\n\t\t} else {\n\t\t\tactionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)\n\t\t\tactionPath = \"\"\n\t\t}\n\n\t\tactionLocation := \"\"\n\t\tif actionPath != \"\" {\n\t\t\tactionLocation = path.Join(actionDir, actionPath)\n\t\t} else {\n\t\t\tactionLocation = actionDir\n\t\t}\n\n\t\tactionName, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc)\n\n\t\tx := action.Runs.Using\n\t\tswitch {\n\t\tcase x.IsNode():\n\t\t\tpopulateEnvsFromSavedState(step.getEnv(), step, rc)\n\t\t\tpopulateEnvsFromInput(ctx, step.getEnv(), step.getActionModel(), rc)\n\n\t\t\tcontainerArgs := []string{rc.GetNodeToolFullPath(ctx), path.Join(containerActionDir, action.Runs.Post)}\n\t\t\tlogger.Debugf(\"executing remote job container: %s\", containerArgs)\n\n\t\t\trc.ApplyExtraPath(ctx, step.getEnv())\n\n\t\t\treturn rc.execJobContainer(containerArgs, *step.getEnv(), \"\", \"\")(ctx)\n\n\t\tcase x.IsDocker():\n\t\t\tif remoteAction == nil {\n\t\t\t\tactionDir = \"\"\n\t\t\t\tactionPath = containerActionDir\n\t\t\t}\n\t\t\treturn execAsDocker(ctx, step, actionName, actionDir, actionPath, remoteAction == nil, \"post-entrypoint\")\n\n\t\tcase x.IsComposite():\n\t\t\tif err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif steps := step.getCompositeSteps(); steps != nil && steps.post != nil {\n\t\t\t\treturn steps.post(ctx)\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"missing steps in composite action\")\n\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/action_cache.go",
    "content": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"path\"\n\t\"strings\"\n\t\"time\"\n\n\tgit \"github.com/go-git/go-git/v5\"\n\tconfig \"github.com/go-git/go-git/v5/config\"\n\t\"github.com/go-git/go-git/v5/plumbing\"\n\t\"github.com/go-git/go-git/v5/plumbing/object\"\n\t\"github.com/go-git/go-git/v5/plumbing/transport\"\n\t\"github.com/go-git/go-git/v5/plumbing/transport/http\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\ntype ActionCache interface {\n\tFetch(ctx context.Context, cacheDir, url, ref, token string) (string, error)\n\tGetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error)\n}\n\ntype GoGitActionCache struct {\n\tPath string\n}\n\nfunc (c GoGitActionCache) Fetch(ctx context.Context, cacheDir, url, ref, token string) (string, error) {\n\tlogger := common.Logger(ctx)\n\n\tgitPath := path.Join(c.Path, safeFilename(cacheDir)+\".git\")\n\n\tlogger.Infof(\"GoGitActionCache fetch %s with ref %s at %s\", url, ref, gitPath)\n\n\tgogitrepo, err := git.PlainInit(gitPath, true)\n\tif errors.Is(err, git.ErrRepositoryAlreadyExists) {\n\t\tlogger.Debugf(\"GoGitActionCache cache hit %s with ref %s at %s\", url, ref, gitPath)\n\t\tgogitrepo, err = git.PlainOpen(gitPath)\n\t}\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"GoGitActionCache failed to open bare git %s with ref %s at %s: %w\", url, ref, gitPath, err)\n\t}\n\ttmpBranch := make([]byte, 12)\n\tif _, err := rand.Read(tmpBranch); err != nil {\n\t\treturn \"\", fmt.Errorf(\"GoGitActionCache failed to generate random tmp branch %s with ref %s at %s: %w\", url, ref, gitPath, err)\n\t}\n\tbranchName := hex.EncodeToString(tmpBranch)\n\n\tvar auth transport.AuthMethod\n\tif token != \"\" {\n\t\tauth = &http.BasicAuth{\n\t\t\tUsername: \"token\",\n\t\t\tPassword: token,\n\t\t}\n\t}\n\tremote, err := gogitrepo.CreateRemoteAnonymous(&config.RemoteConfig{\n\t\tName: \"anonymous\",\n\t\tURLs: []string{\n\t\t\turl,\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"GoGitActionCache failed to create remote %s with ref %s at %s: %w\", url, ref, gitPath, err)\n\t}\n\tdefer func() {\n\t\t_ = gogitrepo.DeleteBranch(branchName)\n\t}()\n\tif err := remote.FetchContext(ctx, &git.FetchOptions{\n\t\tRefSpecs: []config.RefSpec{\n\t\t\tconfig.RefSpec(ref + \":\" + branchName),\n\t\t},\n\t\tAuth:  auth,\n\t\tForce: true,\n\t\tDepth: 1,\n\t}); err != nil {\n\t\treturn \"\", fmt.Errorf(\"GoGitActionCache failed to fetch %s with ref %s at %s: %w\", url, ref, gitPath, err)\n\t}\n\thash, err := gogitrepo.ResolveRevision(plumbing.Revision(branchName))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"GoGitActionCache failed to resolve sha %s with ref %s at %s: %w\", url, ref, gitPath, err)\n\t}\n\tlogger.Infof(\"GoGitActionCache fetch %s with ref %s at %s resolved to %s\", url, ref, gitPath, hash.String())\n\treturn hash.String(), nil\n}\n\ntype GitFileInfo struct {\n\tname    string\n\tsize    int64\n\tmodTime time.Time\n\tisDir   bool\n\tmode    fs.FileMode\n}\n\n// IsDir implements fs.FileInfo.\nfunc (g *GitFileInfo) IsDir() bool {\n\treturn g.isDir\n}\n\n// ModTime implements fs.FileInfo.\nfunc (g *GitFileInfo) ModTime() time.Time {\n\treturn g.modTime\n}\n\n// Mode implements fs.FileInfo.\nfunc (g *GitFileInfo) Mode() fs.FileMode {\n\treturn g.mode\n}\n\n// Name implements fs.FileInfo.\nfunc (g *GitFileInfo) Name() string {\n\treturn g.name\n}\n\n// Size implements fs.FileInfo.\nfunc (g *GitFileInfo) Size() int64 {\n\treturn g.size\n}\n\n// Sys implements fs.FileInfo.\nfunc (g *GitFileInfo) Sys() any {\n\treturn nil\n}\n\nfunc (c GoGitActionCache) GetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error) {\n\tlogger := common.Logger(ctx)\n\n\tgitPath := path.Join(c.Path, safeFilename(cacheDir)+\".git\")\n\n\tlogger.Infof(\"GoGitActionCache get content %s with sha %s subpath '%s' at %s\", cacheDir, sha, includePrefix, gitPath)\n\n\tgogitrepo, err := git.PlainOpen(gitPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GoGitActionCache failed to open bare git %s with sha %s subpath '%s' at %s: %w\", cacheDir, sha, includePrefix, gitPath, err)\n\t}\n\tcommit, err := gogitrepo.CommitObject(plumbing.NewHash(sha))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GoGitActionCache failed to get commit %s with sha %s subpath '%s' at %s: %w\", cacheDir, sha, includePrefix, gitPath, err)\n\t}\n\tt, err := commit.Tree()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GoGitActionCache failed to open git tree %s with sha %s subpath '%s' at %s: %w\", cacheDir, sha, includePrefix, gitPath, err)\n\t}\n\tfiles, err := commit.Files()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GoGitActionCache failed to list files %s with sha %s subpath '%s' at %s: %w\", cacheDir, sha, includePrefix, gitPath, err)\n\t}\n\trpipe, wpipe := io.Pipe()\n\t// Interrupt io.Copy using ctx\n\tch := make(chan int, 1)\n\tgo func() {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\twpipe.CloseWithError(ctx.Err())\n\t\tcase <-ch:\n\t\t}\n\t}()\n\tgo func() {\n\t\tdefer wpipe.Close()\n\t\tdefer close(ch)\n\t\ttw := tar.NewWriter(wpipe)\n\t\tcleanIncludePrefix := path.Clean(includePrefix)\n\t\twpipe.CloseWithError(files.ForEach(func(f *object.File) error {\n\t\t\treturn actionCacheCopyFileOrDir(ctx, cleanIncludePrefix, t, tw, f.Name, f)\n\t\t}))\n\t}()\n\treturn rpipe, err\n}\n\nfunc actionCacheCopyFileOrDir(ctx context.Context, cleanIncludePrefix string, t *object.Tree, tw *tar.Writer, origin string, f *object.File) error {\n\tif err := ctx.Err(); err != nil {\n\t\treturn err\n\t}\n\tname := origin\n\tif strings.HasPrefix(name, cleanIncludePrefix+\"/\") {\n\t\tname = name[len(cleanIncludePrefix)+1:]\n\t} else if cleanIncludePrefix != \".\" && name != cleanIncludePrefix {\n\t\treturn nil\n\t}\n\tfmode, err := f.Mode.ToOSFileMode()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif fmode&fs.ModeSymlink == fs.ModeSymlink {\n\t\tcontent, err := f.Contents()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tdestPath := path.Join(path.Dir(f.Name), content)\n\n\t\tsubtree, err := t.Tree(destPath)\n\t\tif err == nil {\n\t\t\treturn subtree.Files().ForEach(func(ft *object.File) error {\n\t\t\t\treturn actionCacheCopyFileOrDir(ctx, cleanIncludePrefix, t, tw, origin+strings.TrimPrefix(ft.Name, f.Name), f)\n\t\t\t})\n\t\t}\n\n\t\tf, err := t.File(destPath)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"%s (%s): %w\", destPath, origin, err)\n\t\t}\n\t\treturn actionCacheCopyFileOrDir(ctx, cleanIncludePrefix, t, tw, origin, f)\n\t}\n\theader, err := tar.FileInfoHeader(&GitFileInfo{\n\t\tname: name,\n\t\tmode: fmode,\n\t\tsize: f.Size,\n\t}, \"\")\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = tw.WriteHeader(header)\n\tif err != nil {\n\t\treturn err\n\t}\n\treader, err := f.Reader()\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = io.Copy(tw, reader)\n\treturn err\n}\n"
  },
  {
    "path": "pkg/runner/action_cache_offline_mode.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"path\"\n\n\tgit \"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plumbing\"\n\t\"github.com/nektos/act/pkg/common\"\n)\n\ntype GoGitActionCacheOfflineMode struct {\n\tParent GoGitActionCache\n}\n\nfunc (c GoGitActionCacheOfflineMode) Fetch(ctx context.Context, cacheDir, url, ref, token string) (string, error) {\n\tlogger := common.Logger(ctx)\n\n\tgitPath := path.Join(c.Parent.Path, safeFilename(cacheDir)+\".git\")\n\n\tlogger.Infof(\"GoGitActionCacheOfflineMode fetch content %s with ref %s at %s\", url, ref, gitPath)\n\n\tsha, fetchErr := c.Parent.Fetch(ctx, cacheDir, url, ref, token)\n\tgogitrepo, err := git.PlainOpen(gitPath)\n\tif err != nil {\n\t\treturn \"\", fetchErr\n\t}\n\trefName := plumbing.ReferenceName(\"refs/action-cache-offline/\" + ref)\n\tr, err := gogitrepo.Reference(refName, true)\n\tif fetchErr == nil {\n\t\tif err != nil || sha != r.Hash().String() {\n\t\t\tif err == nil {\n\t\t\t\trefName = r.Name()\n\t\t\t}\n\t\t\tref := plumbing.NewHashReference(refName, plumbing.NewHash(sha))\n\t\t\t_ = gogitrepo.Storer.SetReference(ref)\n\t\t}\n\t} else if err == nil {\n\t\treturn r.Hash().String(), nil\n\t}\n\treturn sha, fetchErr\n}\n\nfunc (c GoGitActionCacheOfflineMode) GetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error) {\n\treturn c.Parent.GetTarArchive(ctx, cacheDir, sha, includePrefix)\n}\n"
  },
  {
    "path": "pkg/runner/action_cache_test.go",
    "content": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\n//nolint:gosec\nfunc TestActionCache(t *testing.T) {\n\ta := assert.New(t)\n\tcache := &GoGitActionCache{\n\t\tPath: os.TempDir(),\n\t}\n\tctx := context.Background()\n\tcacheDir := \"nektos/act-test-actions\"\n\trepo := \"https://github.com/nektos/act-test-actions\"\n\trefs := []struct {\n\t\tName     string\n\t\tCacheDir string\n\t\tRepo     string\n\t\tRef      string\n\t}{\n\t\t{\n\t\t\tName:     \"Fetch Branch Name\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repo,\n\t\t\tRef:      \"main\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch Branch Name Absolutely\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repo,\n\t\t\tRef:      \"refs/heads/main\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch HEAD\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repo,\n\t\t\tRef:      \"HEAD\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch Sha\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repo,\n\t\t\tRef:      \"de984ca37e4df4cb9fd9256435a3b82c4a2662b1\",\n\t\t},\n\t}\n\tfor _, c := range refs {\n\t\tt.Run(c.Name, func(_ *testing.T) {\n\t\t\tsha, err := cache.Fetch(ctx, c.CacheDir, c.Repo, c.Ref, \"\")\n\t\t\tif !a.NoError(err) || !a.NotEmpty(sha) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tatar, err := cache.GetTarArchive(ctx, c.CacheDir, sha, \"js\")\n\t\t\tif !a.NoError(err) || !a.NotEmpty(atar) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tmytar := tar.NewReader(atar)\n\t\t\tth, err := mytar.Next()\n\t\t\tif !a.NoError(err) || !a.NotEqual(0, th.Size) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbuf := &bytes.Buffer{}\n\t\t\t// G110: Potential DoS vulnerability via decompression bomb (gosec)\n\t\t\t_, err = io.Copy(buf, mytar)\n\t\t\ta.NoError(err)\n\t\t\tstr := buf.String()\n\t\t\ta.NotEmpty(str)\n\t\t})\n\t}\n}\n\nfunc TestActionCacheFailures(t *testing.T) {\n\ta := assert.New(t)\n\tcache := &GoGitActionCache{\n\t\tPath: os.TempDir(),\n\t}\n\tctx := context.Background()\n\tcacheDir := \"nektos/act-test-actions\"\n\trepo := \"https://github.com/nektos/act-test-actions-not-exist\"\n\trepoExist := \"https://github.com/nektos/act-test-actions\"\n\trefs := []struct {\n\t\tName     string\n\t\tCacheDir string\n\t\tRepo     string\n\t\tRef      string\n\t}{\n\t\t{\n\t\t\tName:     \"Fetch Branch Name\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repo,\n\t\t\tRef:      \"main\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch Branch Name Absolutely\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repo,\n\t\t\tRef:      \"refs/heads/main\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch HEAD\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repo,\n\t\t\tRef:      \"HEAD\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch Sha\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repo,\n\t\t\tRef:      \"de984ca37e4df4cb9fd9256435a3b82c4a2662b1\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch Branch Name no existing\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repoExist,\n\t\t\tRef:      \"main2\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch Branch Name Absolutely no existing\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repoExist,\n\t\t\tRef:      \"refs/heads/main2\",\n\t\t},\n\t\t{\n\t\t\tName:     \"Fetch Sha no existing\",\n\t\t\tCacheDir: cacheDir,\n\t\t\tRepo:     repoExist,\n\t\t\tRef:      \"de984ca37e4df4cb9fd9256435a3b82c4a2662b2\",\n\t\t},\n\t}\n\tfor _, c := range refs {\n\t\tt.Run(c.Name, func(t *testing.T) {\n\t\t\t_, err := cache.Fetch(ctx, c.CacheDir, c.Repo, c.Ref, \"\")\n\t\t\tt.Logf(\"%s\\n\", err)\n\t\t\tif !a.Error(err) {\n\t\t\t\treturn\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/action_composite.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nfunc evaluateCompositeInputAndEnv(ctx context.Context, parent *RunContext, step actionStep) map[string]string {\n\tenv := make(map[string]string)\n\tstepEnv := *step.getEnv()\n\tfor k, v := range stepEnv {\n\t\t// do not set current inputs into composite action\n\t\t// the required inputs are added in the second loop\n\t\tif !strings.HasPrefix(k, \"INPUT_\") {\n\t\t\tenv[k] = v\n\t\t}\n\t}\n\n\tee := parent.NewStepExpressionEvaluator(ctx, step)\n\n\tfor inputID, input := range step.getActionModel().Inputs {\n\t\tenvKey := regexp.MustCompile(\"[^A-Z0-9-]\").ReplaceAllString(strings.ToUpper(inputID), \"_\")\n\t\tenvKey = fmt.Sprintf(\"INPUT_%s\", strings.ToUpper(envKey))\n\n\t\t// lookup if key is defined in the step but the already\n\t\t// evaluated value from the environment\n\t\t_, defined := step.getStepModel().With[inputID]\n\t\tif value, ok := stepEnv[envKey]; defined && ok {\n\t\t\tenv[envKey] = value\n\t\t} else {\n\t\t\t// defaults could contain expressions\n\t\t\tenv[envKey] = ee.Interpolate(ctx, input.Default)\n\t\t}\n\t}\n\tgh := step.getGithubContext(ctx)\n\tenv[\"GITHUB_ACTION_REPOSITORY\"] = gh.ActionRepository\n\tenv[\"GITHUB_ACTION_REF\"] = gh.ActionRef\n\n\treturn env\n}\n\nfunc newCompositeRunContext(ctx context.Context, parent *RunContext, step actionStep, actionPath string) *RunContext {\n\tenv := evaluateCompositeInputAndEnv(ctx, parent, step)\n\n\t// run with the global config but without secrets\n\tconfigCopy := *(parent.Config)\n\tconfigCopy.Secrets = nil\n\n\t// create a run context for the composite action to run in\n\tcompositerc := &RunContext{\n\t\tName:    parent.Name,\n\t\tJobName: parent.JobName,\n\t\tRun: &model.Run{\n\t\t\tJobID: parent.Run.JobID,\n\t\t\tWorkflow: &model.Workflow{\n\t\t\t\tName: parent.Run.Workflow.Name,\n\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\tparent.Run.JobID: {},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tConfig:           &configCopy,\n\t\tStepResults:      map[string]*model.StepResult{},\n\t\tJobContainer:     parent.JobContainer,\n\t\tActionPath:       actionPath,\n\t\tEnv:              env,\n\t\tGlobalEnv:        parent.GlobalEnv,\n\t\tMasks:            parent.Masks,\n\t\tExtraPath:        parent.ExtraPath,\n\t\tParent:           parent,\n\t\tEventJSON:        parent.EventJSON,\n\t\tnodeToolFullPath: parent.nodeToolFullPath,\n\t}\n\tcompositerc.ExprEval = compositerc.NewExpressionEvaluator(ctx)\n\n\treturn compositerc\n}\n\nfunc execAsComposite(step actionStep) common.Executor {\n\trc := step.getRunContext()\n\taction := step.getActionModel()\n\n\treturn func(ctx context.Context) error {\n\t\tcompositeRC := step.getCompositeRunContext(ctx)\n\n\t\tsteps := step.getCompositeSteps()\n\n\t\tif steps == nil || steps.main == nil {\n\t\t\treturn fmt.Errorf(\"missing steps in composite action\")\n\t\t}\n\n\t\tctx = WithCompositeLogger(ctx, &compositeRC.Masks)\n\n\t\terr := steps.main(ctx)\n\n\t\t// Map outputs from composite RunContext to job RunContext\n\t\teval := compositeRC.NewExpressionEvaluator(ctx)\n\t\tfor outputName, output := range action.Outputs {\n\t\t\trc.setOutput(ctx, map[string]string{\n\t\t\t\t\"name\": outputName,\n\t\t\t}, eval.Interpolate(ctx, output.Value))\n\t\t}\n\n\t\trc.Masks = append(rc.Masks, compositeRC.Masks...)\n\t\trc.ExtraPath = compositeRC.ExtraPath\n\t\t// compositeRC.Env is dirty, contains INPUT_ and merged step env, only rely on compositeRC.GlobalEnv\n\t\tmergeIntoMap := mergeIntoMapCaseSensitive\n\t\tif rc.JobContainer.IsEnvironmentCaseInsensitive() {\n\t\t\tmergeIntoMap = mergeIntoMapCaseInsensitive\n\t\t}\n\t\tif rc.GlobalEnv == nil {\n\t\t\trc.GlobalEnv = map[string]string{}\n\t\t}\n\t\tmergeIntoMap(rc.GlobalEnv, compositeRC.GlobalEnv)\n\t\tmergeIntoMap(rc.Env, compositeRC.GlobalEnv)\n\n\t\treturn err\n\t}\n}\n\ntype compositeSteps struct {\n\tpre  common.Executor\n\tmain common.Executor\n\tpost common.Executor\n}\n\n// Executor returns a pipeline executor for all the steps in the job\nfunc (rc *RunContext) compositeExecutor(action *model.Action) *compositeSteps {\n\tsteps := make([]common.Executor, 0)\n\tpreSteps := make([]common.Executor, 0)\n\tvar postExecutor common.Executor\n\n\tsf := &stepFactoryImpl{}\n\n\tfor i, step := range action.Runs.Steps {\n\t\tif step.ID == \"\" {\n\t\t\tstep.ID = fmt.Sprintf(\"%d\", i)\n\t\t}\n\n\t\t// create a copy of the step, since this composite action could\n\t\t// run multiple times and we might modify the instance\n\t\tstepcopy := step\n\n\t\tstep, err := sf.newStep(&stepcopy, rc)\n\t\tif err != nil {\n\t\t\treturn &compositeSteps{\n\t\t\t\tmain: common.NewErrorExecutor(err),\n\t\t\t}\n\t\t}\n\n\t\tstepID := step.getStepModel().ID\n\t\tstepPre := rc.newCompositeCommandExecutor(step.pre())\n\t\tpreSteps = append(preSteps, newCompositeStepLogExecutor(stepPre, stepID))\n\n\t\tsteps = append(steps, func(ctx context.Context) error {\n\t\t\tctx = WithCompositeStepLogger(ctx, stepID)\n\t\t\tlogger := common.Logger(ctx)\n\t\t\terr := rc.newCompositeCommandExecutor(step.main())(ctx)\n\n\t\t\tif err != nil {\n\t\t\t\tlogger.Errorf(\"%v\", err)\n\t\t\t\tcommon.SetJobError(ctx, err)\n\t\t\t} else if ctx.Err() != nil {\n\t\t\t\tlogger.Errorf(\"%v\", ctx.Err())\n\t\t\t\tcommon.SetJobError(ctx, ctx.Err())\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\n\t\t// run the post executor in reverse order\n\t\tif postExecutor != nil {\n\t\t\tstepPost := rc.newCompositeCommandExecutor(step.post())\n\t\t\tpostExecutor = newCompositeStepLogExecutor(stepPost.Finally(postExecutor), stepID)\n\t\t} else {\n\t\t\tstepPost := rc.newCompositeCommandExecutor(step.post())\n\t\t\tpostExecutor = newCompositeStepLogExecutor(stepPost, stepID)\n\t\t}\n\t}\n\n\tsteps = append(steps, common.JobError)\n\treturn &compositeSteps{\n\t\tpre: func(ctx context.Context) error {\n\t\t\treturn common.NewPipelineExecutor(preSteps...)(common.WithJobErrorContainer(ctx))\n\t\t},\n\t\tmain: func(ctx context.Context) error {\n\t\t\treturn common.NewPipelineExecutor(steps...)(common.WithJobErrorContainer(ctx))\n\t\t},\n\t\tpost: postExecutor,\n\t}\n}\n\nfunc (rc *RunContext) newCompositeCommandExecutor(executor common.Executor) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tctx = WithCompositeLogger(ctx, &rc.Masks)\n\n\t\t// We need to inject a composite RunContext related command\n\t\t// handler into the current running job container\n\t\t// We need this, to support scoping commands to the composite action\n\t\t// executing.\n\t\trawLogger := common.Logger(ctx).WithField(\"raw_output\", true)\n\t\tlogWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool {\n\t\t\tif rc.Config.LogOutput {\n\t\t\t\trawLogger.Infof(\"%s\", s)\n\t\t\t} else {\n\t\t\t\trawLogger.Debugf(\"%s\", s)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\n\t\toldout, olderr := rc.JobContainer.ReplaceLogWriter(logWriter, logWriter)\n\t\tdefer rc.JobContainer.ReplaceLogWriter(oldout, olderr)\n\n\t\treturn executor(ctx)\n\t}\n}\n\nfunc newCompositeStepLogExecutor(runStep common.Executor, stepID string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tctx = WithCompositeStepLogger(ctx, stepID)\n\t\tlogger := common.Logger(ctx)\n\t\terr := runStep(ctx)\n\t\tif err != nil {\n\t\t\tlogger.Errorf(\"%v\", err)\n\t\t\tcommon.SetJobError(ctx, err)\n\t\t} else if ctx.Err() != nil {\n\t\t\tlogger.Errorf(\"%v\", ctx.Err())\n\t\t\tcommon.SetJobError(ctx, ctx.Err())\n\t\t}\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/action_test.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"io/fs\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n)\n\ntype closerMock struct {\n\tmock.Mock\n}\n\nfunc (m *closerMock) Close() error {\n\tm.Called()\n\treturn nil\n}\n\nfunc TestActionReader(t *testing.T) {\n\tyaml := strings.ReplaceAll(`\nname: 'name'\nruns:\n\tusing: 'node16'\n\tmain: 'main.js'\n`, \"\\t\", \"  \")\n\n\ttable := []struct {\n\t\tname        string\n\t\tstep        *model.Step\n\t\tfilename    string\n\t\tfileContent string\n\t\texpected    *model.Action\n\t}{\n\t\t{\n\t\t\tname:        \"readActionYml\",\n\t\t\tstep:        &model.Step{},\n\t\t\tfilename:    \"action.yml\",\n\t\t\tfileContent: yaml,\n\t\t\texpected: &model.Action{\n\t\t\t\tName: \"name\",\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tMain:   \"main.js\",\n\t\t\t\t\tPreIf:  \"always()\",\n\t\t\t\t\tPostIf: \"always()\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:        \"readActionYaml\",\n\t\t\tstep:        &model.Step{},\n\t\t\tfilename:    \"action.yaml\",\n\t\t\tfileContent: yaml,\n\t\t\texpected: &model.Action{\n\t\t\t\tName: \"name\",\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tMain:   \"main.js\",\n\t\t\t\t\tPreIf:  \"always()\",\n\t\t\t\t\tPostIf: \"always()\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:        \"readDockerfile\",\n\t\t\tstep:        &model.Step{},\n\t\t\tfilename:    \"Dockerfile\",\n\t\t\tfileContent: \"FROM ubuntu:20.04\",\n\t\t\texpected: &model.Action{\n\t\t\t\tName: \"(Synthetic)\",\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing: \"docker\",\n\t\t\t\t\tImage: \"Dockerfile\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"readWithArgs\",\n\t\t\tstep: &model.Step{\n\t\t\t\tWith: map[string]string{\n\t\t\t\t\t\"args\": \"cmd\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: &model.Action{\n\t\t\t\tName: \"(Synthetic)\",\n\t\t\t\tInputs: map[string]model.Input{\n\t\t\t\t\t\"cwd\": {\n\t\t\t\t\t\tDescription: \"(Actual working directory)\",\n\t\t\t\t\t\tRequired:    false,\n\t\t\t\t\t\tDefault:     \"actionDir/actionPath\",\n\t\t\t\t\t},\n\t\t\t\t\t\"command\": {\n\t\t\t\t\t\tDescription: \"(Actual program)\",\n\t\t\t\t\t\tRequired:    false,\n\t\t\t\t\t\tDefault:     \"cmd\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing: \"node12\",\n\t\t\t\t\tMain:  \"trampoline.js\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tcloserMock := &closerMock{}\n\n\t\t\treadFile := func(filename string) (io.Reader, io.Closer, error) {\n\t\t\t\tif tt.filename != filename {\n\t\t\t\t\treturn nil, nil, fs.ErrNotExist\n\t\t\t\t}\n\n\t\t\t\treturn strings.NewReader(tt.fileContent), closerMock, nil\n\t\t\t}\n\n\t\t\twriteFile := func(filename string, _ []byte, perm fs.FileMode) error {\n\t\t\t\tassert.Equal(t, \"actionDir/actionPath/trampoline.js\", filename)\n\t\t\t\tassert.Equal(t, fs.FileMode(0400), perm)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif tt.filename != \"\" {\n\t\t\t\tcloserMock.On(\"Close\")\n\t\t\t}\n\n\t\t\taction, err := readActionImpl(context.Background(), tt.step, \"actionDir\", \"actionPath\", readFile, writeFile)\n\n\t\t\tassert.Nil(t, err)\n\t\t\tassert.Equal(t, tt.expected, action)\n\n\t\t\tcloserMock.AssertExpectations(t)\n\t\t})\n\t}\n}\n\nfunc TestActionRunner(t *testing.T) {\n\ttable := []struct {\n\t\tname        string\n\t\tstep        actionStep\n\t\texpectedEnv map[string]string\n\t}{\n\t\t{\n\t\t\tname: \"with-input\",\n\t\t\tstep: &stepActionRemote{\n\t\t\t\tStep: &model.Step{\n\t\t\t\t\tUses: \"org/repo/path@ref\",\n\t\t\t\t},\n\t\t\t\tRunContext: &RunContext{\n\t\t\t\t\tConfig: &Config{},\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tJobID: \"job\",\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\t\"job\": {\n\t\t\t\t\t\t\t\t\tName: \"job\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tnodeToolFullPath: \"node\",\n\t\t\t\t},\n\t\t\t\taction: &model.Action{\n\t\t\t\t\tInputs: map[string]model.Input{\n\t\t\t\t\t\t\"key\": {\n\t\t\t\t\t\t\tDefault: \"default value\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\t\tUsing: \"node16\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tenv: map[string]string{},\n\t\t\t},\n\t\t\texpectedEnv: map[string]string{\"INPUT_KEY\": \"default value\"},\n\t\t},\n\t\t{\n\t\t\tname: \"restore-saved-state\",\n\t\t\tstep: &stepActionRemote{\n\t\t\t\tStep: &model.Step{\n\t\t\t\t\tID:   \"step\",\n\t\t\t\t\tUses: \"org/repo/path@ref\",\n\t\t\t\t},\n\t\t\t\tRunContext: &RunContext{\n\t\t\t\t\tActionPath: \"path\",\n\t\t\t\t\tConfig:     &Config{},\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tJobID: \"job\",\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\t\"job\": {\n\t\t\t\t\t\t\t\t\tName: \"job\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tCurrentStep: \"post-step\",\n\t\t\t\t\tStepResults: map[string]*model.StepResult{\n\t\t\t\t\t\t\"step\": {},\n\t\t\t\t\t},\n\t\t\t\t\tIntraActionState: map[string]map[string]string{\n\t\t\t\t\t\t\"step\": {\n\t\t\t\t\t\t\t\"name\": \"state value\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tnodeToolFullPath: \"node\",\n\t\t\t\t},\n\t\t\t\taction: &model.Action{\n\t\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\t\tUsing: \"node16\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tenv: map[string]string{},\n\t\t\t},\n\t\t\texpectedEnv: map[string]string{\"STATE_name\": \"state value\"},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\n\t\t\tcm := &containerMock{}\n\t\t\tcm.On(\"CopyDir\", \"/var/run/act/actions/dir/\", \"dir/\", false).Return(func(_ context.Context) error { return nil })\n\n\t\t\tenvMatcher := mock.MatchedBy(func(env map[string]string) bool {\n\t\t\t\tfor k, v := range tt.expectedEnv {\n\t\t\t\t\tif env[k] != v {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true\n\t\t\t})\n\n\t\t\tcm.On(\"Exec\", []string{\"node\", \"/var/run/act/actions/dir/path\"}, envMatcher, \"\", \"\").Return(func(_ context.Context) error { return nil })\n\n\t\t\ttt.step.getRunContext().JobContainer = cm\n\n\t\t\terr := runActionImpl(tt.step, \"dir\", newRemoteAction(\"org/repo/path@ref\"))(ctx)\n\n\t\t\tassert.Nil(t, err)\n\t\t\tcm.AssertExpectations(t)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/command.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\nvar commandPatternGA *regexp.Regexp\nvar commandPatternADO *regexp.Regexp\n\nfunc init() {\n\tcommandPatternGA = regexp.MustCompile(\"^::([^ ]+)( (.+))?::([^\\r\\n]*)[\\r\\n]+$\")\n\tcommandPatternADO = regexp.MustCompile(\"^##\\\\[([^ ]+)( (.+))?]([^\\r\\n]*)[\\r\\n]+$\")\n}\n\nfunc tryParseRawActionCommand(line string) (command string, kvPairs map[string]string, arg string, ok bool) {\n\tif m := commandPatternGA.FindStringSubmatch(line); m != nil {\n\t\tcommand = m[1]\n\t\tkvPairs = parseKeyValuePairs(m[3], \",\")\n\t\targ = m[4]\n\t\tok = true\n\t} else if m := commandPatternADO.FindStringSubmatch(line); m != nil {\n\t\tcommand = m[1]\n\t\tkvPairs = parseKeyValuePairs(m[3], \";\")\n\t\targ = m[4]\n\t\tok = true\n\t}\n\treturn\n}\n\nfunc (rc *RunContext) commandHandler(ctx context.Context) common.LineHandler {\n\tlogger := common.Logger(ctx)\n\tresumeCommand := \"\"\n\treturn func(line string) bool {\n\t\tcommand, kvPairs, arg, ok := tryParseRawActionCommand(line)\n\t\tif !ok {\n\t\t\treturn true\n\t\t}\n\n\t\tif resumeCommand != \"\" && command != resumeCommand {\n\t\t\tlogger.WithFields(logrus.Fields{\"command\": \"ignored\", \"raw\": line}).Infof(\"  \\U00002699  %s\", line)\n\t\t\treturn false\n\t\t}\n\t\targ = unescapeCommandData(arg)\n\t\tkvPairs = unescapeKvPairs(kvPairs)\n\t\tdefCommandLogger := logger.WithFields(logrus.Fields{\"command\": command, \"kvPairs\": kvPairs, \"arg\": arg, \"raw\": line})\n\t\tswitch command {\n\t\tcase \"set-env\":\n\t\t\trc.setEnv(ctx, kvPairs, arg)\n\t\tcase \"set-output\":\n\t\t\trc.setOutput(ctx, kvPairs, arg)\n\t\tcase \"add-path\":\n\t\t\trc.addPath(ctx, arg)\n\t\tcase \"debug\":\n\t\t\tdefCommandLogger.Debugf(\"  \\U0001F4AC  %s\", line)\n\t\tcase \"warning\":\n\t\t\tdefCommandLogger.Warnf(\"  \\U0001F6A7  %s\", line)\n\t\tcase \"error\":\n\t\t\tdefCommandLogger.Errorf(\"  \\U00002757  %s\", line)\n\t\tcase \"add-mask\":\n\t\t\trc.AddMask(arg)\n\t\t\tdefCommandLogger.Infof(\"  \\U00002699  %s\", \"***\")\n\t\tcase \"stop-commands\":\n\t\t\tresumeCommand = arg\n\t\t\tdefCommandLogger.Infof(\"  \\U00002699  %s\", line)\n\t\tcase resumeCommand:\n\t\t\tresumeCommand = \"\"\n\t\t\tdefCommandLogger.Infof(\"  \\U00002699  %s\", line)\n\t\tcase \"save-state\":\n\t\t\tdefCommandLogger.Infof(\"  \\U0001f4be  %s\", line)\n\t\t\trc.saveState(ctx, kvPairs, arg)\n\t\tcase \"add-matcher\":\n\t\t\tdefCommandLogger.Infof(\"  \\U00002753 add-matcher %s\", arg)\n\t\tdefault:\n\t\t\tdefCommandLogger.Infof(\"  \\U00002753  %s\", line)\n\t\t}\n\n\t\treturn false\n\t}\n}\n\nfunc (rc *RunContext) setEnv(ctx context.Context, kvPairs map[string]string, arg string) {\n\tname := kvPairs[\"name\"]\n\tcommon.Logger(ctx).WithFields(logrus.Fields{\"command\": \"set-env\", \"name\": name, \"arg\": arg}).Infof(\"  \\U00002699  ::set-env:: %s=%s\", name, arg)\n\tif rc.Env == nil {\n\t\trc.Env = make(map[string]string)\n\t}\n\tif rc.GlobalEnv == nil {\n\t\trc.GlobalEnv = map[string]string{}\n\t}\n\tnewenv := map[string]string{\n\t\tname: arg,\n\t}\n\tmergeIntoMap := mergeIntoMapCaseSensitive\n\tif rc.JobContainer != nil && rc.JobContainer.IsEnvironmentCaseInsensitive() {\n\t\tmergeIntoMap = mergeIntoMapCaseInsensitive\n\t}\n\tmergeIntoMap(rc.Env, newenv)\n\tmergeIntoMap(rc.GlobalEnv, newenv)\n}\nfunc (rc *RunContext) setOutput(ctx context.Context, kvPairs map[string]string, arg string) {\n\tlogger := common.Logger(ctx)\n\tstepID := rc.CurrentStep\n\toutputName := kvPairs[\"name\"]\n\tif outputMapping, ok := rc.OutputMappings[MappableOutput{StepID: stepID, OutputName: outputName}]; ok {\n\t\tstepID = outputMapping.StepID\n\t\toutputName = outputMapping.OutputName\n\t}\n\n\tresult, ok := rc.StepResults[stepID]\n\tif !ok {\n\t\tlogger.Infof(\"  \\U00002757  no outputs used step '%s'\", stepID)\n\t\treturn\n\t}\n\n\tlogger.WithFields(logrus.Fields{\"command\": \"set-output\", \"name\": outputName, \"arg\": arg}).Infof(\"  \\U00002699  ::set-output:: %s=%s\", outputName, arg)\n\tresult.Outputs[outputName] = arg\n}\nfunc (rc *RunContext) addPath(ctx context.Context, arg string) {\n\tcommon.Logger(ctx).WithFields(logrus.Fields{\"command\": \"add-path\", \"arg\": arg}).Infof(\"  \\U00002699  ::add-path:: %s\", arg)\n\textraPath := []string{arg}\n\tfor _, v := range rc.ExtraPath {\n\t\tif v != arg {\n\t\t\textraPath = append(extraPath, v)\n\t\t}\n\t}\n\trc.ExtraPath = extraPath\n}\n\nfunc parseKeyValuePairs(kvPairs string, separator string) map[string]string {\n\trtn := make(map[string]string)\n\tkvPairList := strings.Split(kvPairs, separator)\n\tfor _, kvPair := range kvPairList {\n\t\tkv := strings.Split(kvPair, \"=\")\n\t\tif len(kv) == 2 {\n\t\t\trtn[kv[0]] = kv[1]\n\t\t}\n\t}\n\treturn rtn\n}\nfunc unescapeCommandData(arg string) string {\n\tescapeMap := map[string]string{\n\t\t\"%25\": \"%\",\n\t\t\"%0D\": \"\\r\",\n\t\t\"%0A\": \"\\n\",\n\t}\n\tfor k, v := range escapeMap {\n\t\targ = strings.ReplaceAll(arg, k, v)\n\t}\n\treturn arg\n}\nfunc unescapeCommandProperty(arg string) string {\n\tescapeMap := map[string]string{\n\t\t\"%25\": \"%\",\n\t\t\"%0D\": \"\\r\",\n\t\t\"%0A\": \"\\n\",\n\t\t\"%3A\": \":\",\n\t\t\"%2C\": \",\",\n\t}\n\tfor k, v := range escapeMap {\n\t\targ = strings.ReplaceAll(arg, k, v)\n\t}\n\treturn arg\n}\nfunc unescapeKvPairs(kvPairs map[string]string) map[string]string {\n\tfor k, v := range kvPairs {\n\t\tkvPairs[k] = unescapeCommandProperty(v)\n\t}\n\treturn kvPairs\n}\n\nfunc (rc *RunContext) saveState(_ context.Context, kvPairs map[string]string, arg string) {\n\tstepID := rc.CurrentStep\n\tif stepID != \"\" {\n\t\tif rc.IntraActionState == nil {\n\t\t\trc.IntraActionState = map[string]map[string]string{}\n\t\t}\n\t\tstate, ok := rc.IntraActionState[stepID]\n\t\tif !ok {\n\t\t\tstate = map[string]string{}\n\t\t\trc.IntraActionState[stepID] = state\n\t\t}\n\t\tstate[kvPairs[\"name\"]] = arg\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/command_test.go",
    "content": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/sirupsen/logrus/hooks/test\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nfunc TestSetEnv(t *testing.T) {\n\ta := assert.New(t)\n\tctx := context.Background()\n\trc := new(RunContext)\n\thandler := rc.commandHandler(ctx)\n\n\thandler(\"::set-env name=x::valz\\n\")\n\ta.Equal(\"valz\", rc.Env[\"x\"])\n}\n\nfunc TestSetOutput(t *testing.T) {\n\ta := assert.New(t)\n\tctx := context.Background()\n\trc := new(RunContext)\n\trc.StepResults = make(map[string]*model.StepResult)\n\thandler := rc.commandHandler(ctx)\n\n\trc.CurrentStep = \"my-step\"\n\trc.StepResults[rc.CurrentStep] = &model.StepResult{\n\t\tOutputs: make(map[string]string),\n\t}\n\thandler(\"::set-output name=x::valz\\n\")\n\ta.Equal(\"valz\", rc.StepResults[\"my-step\"].Outputs[\"x\"])\n\n\thandler(\"::set-output name=x::percent2%25\\n\")\n\ta.Equal(\"percent2%\", rc.StepResults[\"my-step\"].Outputs[\"x\"])\n\n\thandler(\"::set-output name=x::percent2%25%0Atest\\n\")\n\ta.Equal(\"percent2%\\ntest\", rc.StepResults[\"my-step\"].Outputs[\"x\"])\n\n\thandler(\"::set-output name=x::percent2%25%0Atest another3%25test\\n\")\n\ta.Equal(\"percent2%\\ntest another3%test\", rc.StepResults[\"my-step\"].Outputs[\"x\"])\n\n\thandler(\"::set-output name=x%3A::percent2%25%0Atest\\n\")\n\ta.Equal(\"percent2%\\ntest\", rc.StepResults[\"my-step\"].Outputs[\"x:\"])\n\n\thandler(\"::set-output name=x%3A%2C%0A%25%0D%3A::percent2%25%0Atest\\n\")\n\ta.Equal(\"percent2%\\ntest\", rc.StepResults[\"my-step\"].Outputs[\"x:,\\n%\\r:\"])\n}\n\nfunc TestAddpath(t *testing.T) {\n\ta := assert.New(t)\n\tctx := context.Background()\n\trc := new(RunContext)\n\thandler := rc.commandHandler(ctx)\n\n\thandler(\"::add-path::/zoo\\n\")\n\ta.Equal(\"/zoo\", rc.ExtraPath[0])\n\n\thandler(\"::add-path::/boo\\n\")\n\ta.Equal(\"/boo\", rc.ExtraPath[0])\n}\n\nfunc TestStopCommands(t *testing.T) {\n\tlogger, hook := test.NewNullLogger()\n\n\ta := assert.New(t)\n\tctx := common.WithLogger(context.Background(), logger)\n\trc := new(RunContext)\n\thandler := rc.commandHandler(ctx)\n\n\thandler(\"::set-env name=x::valz\\n\")\n\ta.Equal(\"valz\", rc.Env[\"x\"])\n\thandler(\"::stop-commands::my-end-token\\n\")\n\thandler(\"::set-env name=x::abcd\\n\")\n\ta.Equal(\"valz\", rc.Env[\"x\"])\n\thandler(\"::my-end-token::\\n\")\n\thandler(\"::set-env name=x::abcd\\n\")\n\ta.Equal(\"abcd\", rc.Env[\"x\"])\n\n\tmessages := make([]string, 0)\n\tfor _, entry := range hook.AllEntries() {\n\t\tmessages = append(messages, entry.Message)\n\t}\n\n\ta.Contains(messages, \"  \\U00002699  ::set-env name=x::abcd\\n\")\n}\n\nfunc TestAddpathADO(t *testing.T) {\n\ta := assert.New(t)\n\tctx := context.Background()\n\trc := new(RunContext)\n\thandler := rc.commandHandler(ctx)\n\n\thandler(\"##[add-path]/zoo\\n\")\n\ta.Equal(\"/zoo\", rc.ExtraPath[0])\n\n\thandler(\"##[add-path]/boo\\n\")\n\ta.Equal(\"/boo\", rc.ExtraPath[0])\n}\n\nfunc TestAddmask(t *testing.T) {\n\tlogger, hook := test.NewNullLogger()\n\n\ta := assert.New(t)\n\tctx := context.Background()\n\tloggerCtx := common.WithLogger(ctx, logger)\n\n\trc := new(RunContext)\n\thandler := rc.commandHandler(loggerCtx)\n\thandler(\"::add-mask::my-secret-value\\n\")\n\n\ta.Equal(\"  \\U00002699  ***\", hook.LastEntry().Message)\n\ta.NotEqual(\"  \\U00002699  *my-secret-value\", hook.LastEntry().Message)\n}\n\n// based on https://stackoverflow.com/a/10476304\nfunc captureOutput(t *testing.T, f func()) string {\n\told := os.Stdout\n\tr, w, _ := os.Pipe()\n\tos.Stdout = w\n\n\tf()\n\n\toutC := make(chan string)\n\n\tgo func() {\n\t\tvar buf bytes.Buffer\n\t\t_, err := io.Copy(&buf, r)\n\t\tif err != nil {\n\t\t\ta := assert.New(t)\n\t\t\ta.Fail(\"io.Copy failed\")\n\t\t}\n\t\toutC <- buf.String()\n\t}()\n\n\tw.Close()\n\tos.Stdout = old\n\tout := <-outC\n\n\treturn out\n}\n\nfunc TestAddmaskUsemask(t *testing.T) {\n\trc := new(RunContext)\n\trc.StepResults = make(map[string]*model.StepResult)\n\trc.CurrentStep = \"my-step\"\n\trc.StepResults[rc.CurrentStep] = &model.StepResult{\n\t\tOutputs: make(map[string]string),\n\t}\n\n\ta := assert.New(t)\n\n\tconfig := &Config{\n\t\tSecrets:         map[string]string{},\n\t\tInsecureSecrets: false,\n\t}\n\n\tre := captureOutput(t, func() {\n\t\tctx := context.Background()\n\t\tctx = WithJobLogger(ctx, \"0\", \"testjob\", config, &rc.Masks, map[string]interface{}{})\n\n\t\thandler := rc.commandHandler(ctx)\n\t\thandler(\"::add-mask::secret\\n\")\n\t\thandler(\"::set-output:: token=secret\\n\")\n\t})\n\n\ta.Equal(\"[testjob]   \\U00002699  ***\\n[testjob]   \\U00002699  ::set-output:: = token=***\\n\", re)\n}\n\nfunc TestSaveState(t *testing.T) {\n\trc := &RunContext{\n\t\tCurrentStep: \"step\",\n\t\tStepResults: map[string]*model.StepResult{},\n\t}\n\n\tctx := context.Background()\n\n\thandler := rc.commandHandler(ctx)\n\thandler(\"::save-state name=state-name::state-value\\n\")\n\n\tassert.Equal(t, \"state-value\", rc.IntraActionState[\"step\"][\"state-name\"])\n}\n"
  },
  {
    "path": "pkg/runner/container_mock_test.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/stretchr/testify/mock\"\n)\n\ntype containerMock struct {\n\tmock.Mock\n\tcontainer.Container\n\tcontainer.LinuxContainerEnvironmentExtensions\n}\n\nfunc (cm *containerMock) Create(capAdd []string, capDrop []string) common.Executor {\n\targs := cm.Called(capAdd, capDrop)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) Pull(forcePull bool) common.Executor {\n\targs := cm.Called(forcePull)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) Start(attach bool) common.Executor {\n\targs := cm.Called(attach)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) Remove() common.Executor {\n\targs := cm.Called()\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) Close() common.Executor {\n\targs := cm.Called()\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) UpdateFromEnv(srcPath string, env *map[string]string) common.Executor {\n\targs := cm.Called(srcPath, env)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) UpdateFromImageEnv(env *map[string]string) common.Executor {\n\targs := cm.Called(env)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) Copy(destPath string, files ...*container.FileEntry) common.Executor {\n\targs := cm.Called(destPath, files)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) CopyDir(destPath string, srcPath string, useGitIgnore bool) common.Executor {\n\targs := cm.Called(destPath, srcPath, useGitIgnore)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) Exec(command []string, env map[string]string, user, workdir string) common.Executor {\n\targs := cm.Called(command, env, user, workdir)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (cm *containerMock) GetContainerArchive(ctx context.Context, srcPath string) (io.ReadCloser, error) {\n\targs := cm.Called(ctx, srcPath)\n\terr, hasErr := args.Get(1).(error)\n\tif !hasErr {\n\t\terr = nil\n\t}\n\treturn args.Get(0).(io.ReadCloser), err\n}\n"
  },
  {
    "path": "pkg/runner/expression.go",
    "content": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"path\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t_ \"embed\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/exprparser\"\n\t\"github.com/nektos/act/pkg/model\"\n\t\"gopkg.in/yaml.v3\"\n)\n\n// ExpressionEvaluator is the interface for evaluating expressions\ntype ExpressionEvaluator interface {\n\tevaluate(context.Context, string, exprparser.DefaultStatusCheck) (interface{}, error)\n\tEvaluateYamlNode(context.Context, *yaml.Node) error\n\tInterpolate(context.Context, string) string\n}\n\n// NewExpressionEvaluator creates a new evaluator\nfunc (rc *RunContext) NewExpressionEvaluator(ctx context.Context) ExpressionEvaluator {\n\treturn rc.NewExpressionEvaluatorWithEnv(ctx, rc.GetEnv())\n}\n\nfunc (rc *RunContext) NewExpressionEvaluatorWithEnv(ctx context.Context, env map[string]string) ExpressionEvaluator {\n\tvar workflowCallResult map[string]*model.WorkflowCallResult\n\n\t// todo: cleanup EvaluationEnvironment creation\n\tusing := make(map[string]exprparser.Needs)\n\tstrategy := make(map[string]interface{})\n\tif rc.Run != nil {\n\t\tjob := rc.Run.Job()\n\t\tif job != nil && job.Strategy != nil {\n\t\t\tstrategy[\"fail-fast\"] = job.Strategy.FailFast\n\t\t\tstrategy[\"max-parallel\"] = job.Strategy.MaxParallel\n\t\t}\n\n\t\tjobs := rc.Run.Workflow.Jobs\n\t\tjobNeeds := rc.Run.Job().Needs()\n\n\t\tfor _, needs := range jobNeeds {\n\t\t\tusing[needs] = exprparser.Needs{\n\t\t\t\tOutputs: jobs[needs].Outputs,\n\t\t\t\tResult:  jobs[needs].Result,\n\t\t\t}\n\t\t}\n\n\t\t// only setup jobs context in case of workflow_call\n\t\t// and existing expression evaluator (this means, jobs are at\n\t\t// least ready to run)\n\t\tif rc.caller != nil && rc.ExprEval != nil {\n\t\t\tworkflowCallResult = map[string]*model.WorkflowCallResult{}\n\n\t\t\tfor jobName, job := range jobs {\n\t\t\t\tresult := model.WorkflowCallResult{\n\t\t\t\t\tOutputs: map[string]string{},\n\t\t\t\t}\n\t\t\t\tfor k, v := range job.Outputs {\n\t\t\t\t\tresult.Outputs[k] = v\n\t\t\t\t}\n\t\t\t\tworkflowCallResult[jobName] = &result\n\t\t\t}\n\t\t}\n\t}\n\n\tghc := rc.getGithubContext(ctx)\n\tinputs := getEvaluatorInputs(ctx, rc, nil, ghc)\n\n\tee := &exprparser.EvaluationEnvironment{\n\t\tGithub: ghc,\n\t\tEnv:    env,\n\t\tJob:    rc.getJobContext(),\n\t\tJobs:   &workflowCallResult,\n\t\t// todo: should be unavailable\n\t\t// but required to interpolate/evaluate the step outputs on the job\n\t\tSteps:     rc.getStepsContext(),\n\t\tSecrets:   getWorkflowSecrets(ctx, rc),\n\t\tVars:      getWorkflowVars(ctx, rc),\n\t\tStrategy:  strategy,\n\t\tMatrix:    rc.Matrix,\n\t\tNeeds:     using,\n\t\tInputs:    inputs,\n\t\tHashFiles: getHashFilesFunction(ctx, rc),\n\t}\n\tif rc.JobContainer != nil {\n\t\tee.Runner = rc.JobContainer.GetRunnerContext(ctx)\n\t}\n\treturn expressionEvaluator{\n\t\tinterpreter: exprparser.NewInterpeter(ee, exprparser.Config{\n\t\t\tRun:        rc.Run,\n\t\t\tWorkingDir: rc.Config.Workdir,\n\t\t\tContext:    \"job\",\n\t\t}),\n\t}\n}\n\n//go:embed hashfiles/index.js\nvar hashfiles string\n\n// NewStepExpressionEvaluator creates a new evaluator\nfunc (rc *RunContext) NewStepExpressionEvaluator(ctx context.Context, step step) ExpressionEvaluator {\n\treturn rc.NewStepExpressionEvaluatorExt(ctx, step, false)\n}\n\n// NewStepExpressionEvaluatorExt creates a new evaluator\nfunc (rc *RunContext) NewStepExpressionEvaluatorExt(ctx context.Context, step step, rcInputs bool) ExpressionEvaluator {\n\tghc := rc.getGithubContext(ctx)\n\tif rcInputs {\n\t\treturn rc.newStepExpressionEvaluator(ctx, step, ghc, getEvaluatorInputs(ctx, rc, nil, ghc))\n\t}\n\treturn rc.newStepExpressionEvaluator(ctx, step, ghc, getEvaluatorInputs(ctx, rc, step, ghc))\n}\n\nfunc (rc *RunContext) newStepExpressionEvaluator(ctx context.Context, step step, _ *model.GithubContext, inputs map[string]interface{}) ExpressionEvaluator {\n\t// todo: cleanup EvaluationEnvironment creation\n\tjob := rc.Run.Job()\n\tstrategy := make(map[string]interface{})\n\tif job.Strategy != nil {\n\t\tstrategy[\"fail-fast\"] = job.Strategy.FailFast\n\t\tstrategy[\"max-parallel\"] = job.Strategy.MaxParallel\n\t}\n\n\tjobs := rc.Run.Workflow.Jobs\n\tjobNeeds := rc.Run.Job().Needs()\n\n\tusing := make(map[string]exprparser.Needs)\n\tfor _, needs := range jobNeeds {\n\t\tusing[needs] = exprparser.Needs{\n\t\t\tOutputs: jobs[needs].Outputs,\n\t\t\tResult:  jobs[needs].Result,\n\t\t}\n\t}\n\n\tee := &exprparser.EvaluationEnvironment{\n\t\tGithub:   step.getGithubContext(ctx),\n\t\tEnv:      *step.getEnv(),\n\t\tJob:      rc.getJobContext(),\n\t\tSteps:    rc.getStepsContext(),\n\t\tSecrets:  getWorkflowSecrets(ctx, rc),\n\t\tVars:     getWorkflowVars(ctx, rc),\n\t\tStrategy: strategy,\n\t\tMatrix:   rc.Matrix,\n\t\tNeeds:    using,\n\t\t// todo: should be unavailable\n\t\t// but required to interpolate/evaluate the inputs in actions/composite\n\t\tInputs:    inputs,\n\t\tHashFiles: getHashFilesFunction(ctx, rc),\n\t}\n\tif rc.JobContainer != nil {\n\t\tee.Runner = rc.JobContainer.GetRunnerContext(ctx)\n\t}\n\treturn expressionEvaluator{\n\t\tinterpreter: exprparser.NewInterpeter(ee, exprparser.Config{\n\t\t\tRun:        rc.Run,\n\t\t\tWorkingDir: rc.Config.Workdir,\n\t\t\tContext:    \"step\",\n\t\t}),\n\t}\n}\n\nfunc getHashFilesFunction(ctx context.Context, rc *RunContext) func(v []reflect.Value) (interface{}, error) {\n\thashFiles := func(v []reflect.Value) (interface{}, error) {\n\t\tif rc.JobContainer != nil {\n\t\t\ttimeed, cancel := context.WithTimeout(ctx, time.Minute)\n\t\t\tdefer cancel()\n\t\t\tname := \"workflow/hashfiles/index.js\"\n\t\t\thout := &bytes.Buffer{}\n\t\t\therr := &bytes.Buffer{}\n\t\t\tpatterns := []string{}\n\t\t\tfollowSymlink := false\n\n\t\t\tfor i, p := range v {\n\t\t\t\ts := p.String()\n\t\t\t\tif i == 0 {\n\t\t\t\t\tif strings.HasPrefix(s, \"--\") {\n\t\t\t\t\t\tif strings.EqualFold(s, \"--follow-symbolic-links\") {\n\t\t\t\t\t\t\tfollowSymlink = true\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn \"\", fmt.Errorf(\"Invalid glob option %s, available option: '--follow-symbolic-links'\", s)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpatterns = append(patterns, s)\n\t\t\t}\n\t\t\tenv := map[string]string{}\n\t\t\tfor k, v := range rc.Env {\n\t\t\t\tenv[k] = v\n\t\t\t}\n\t\t\tenv[\"patterns\"] = strings.Join(patterns, \"\\n\")\n\t\t\tif followSymlink {\n\t\t\t\tenv[\"followSymbolicLinks\"] = \"true\"\n\t\t\t}\n\n\t\t\tstdout, stderr := rc.JobContainer.ReplaceLogWriter(hout, herr)\n\t\t\t_ = rc.JobContainer.Copy(rc.JobContainer.GetActPath(), &container.FileEntry{\n\t\t\t\tName: name,\n\t\t\t\tMode: 0o644,\n\t\t\t\tBody: hashfiles,\n\t\t\t}).\n\t\t\t\tThen(rc.execJobContainer([]string{rc.GetNodeToolFullPath(ctx), path.Join(rc.JobContainer.GetActPath(), name)},\n\t\t\t\t\tenv, \"\", \"\")).\n\t\t\t\tFinally(func(context.Context) error {\n\t\t\t\t\trc.JobContainer.ReplaceLogWriter(stdout, stderr)\n\t\t\t\t\treturn nil\n\t\t\t\t})(timeed)\n\t\t\toutput := hout.String() + \"\\n\" + herr.String()\n\t\t\tguard := \"__OUTPUT__\"\n\t\t\toutstart := strings.Index(output, guard)\n\t\t\tif outstart != -1 {\n\t\t\t\toutstart += len(guard)\n\t\t\t\toutend := strings.Index(output[outstart:], guard)\n\t\t\t\tif outend != -1 {\n\t\t\t\t\treturn output[outstart : outstart+outend], nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn \"\", nil\n\t}\n\treturn hashFiles\n}\n\ntype expressionEvaluator struct {\n\tinterpreter exprparser.Interpreter\n}\n\nfunc (ee expressionEvaluator) evaluate(ctx context.Context, in string, defaultStatusCheck exprparser.DefaultStatusCheck) (interface{}, error) {\n\tlogger := common.Logger(ctx)\n\tlogger.Debugf(\"evaluating expression '%s'\", in)\n\tevaluated, err := ee.interpreter.Evaluate(in, defaultStatusCheck)\n\n\tprintable := regexp.MustCompile(`::add-mask::.*`).ReplaceAllString(fmt.Sprintf(\"%t\", evaluated), \"::add-mask::***)\")\n\tlogger.Debugf(\"expression '%s' evaluated to '%s'\", in, printable)\n\n\treturn evaluated, err\n}\n\nfunc (ee expressionEvaluator) evaluateScalarYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {\n\tvar in string\n\tif err := node.Decode(&in); err != nil {\n\t\treturn nil, err\n\t}\n\tif !strings.Contains(in, \"${{\") || !strings.Contains(in, \"}}\") {\n\t\treturn nil, nil\n\t}\n\texpr, _ := rewriteSubExpression(ctx, in, false)\n\tres, err := ee.evaluate(ctx, expr, exprparser.DefaultStatusCheckNone)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tret := &yaml.Node{}\n\tif err := ret.Encode(res); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ret, err\n}\n\nfunc (ee expressionEvaluator) evaluateMappingYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {\n\tvar ret *yaml.Node\n\t// GitHub has this undocumented feature to merge maps, called insert directive\n\tinsertDirective := regexp.MustCompile(`\\${{\\s*insert\\s*}}`)\n\tfor i := 0; i < len(node.Content)/2; i++ {\n\t\tchanged := func() error {\n\t\t\tif ret == nil {\n\t\t\t\tret = &yaml.Node{}\n\t\t\t\tif err := ret.Encode(node); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tret.Content = ret.Content[:i*2]\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\tk := node.Content[i*2]\n\t\tv := node.Content[i*2+1]\n\t\tev, err := ee.evaluateYamlNodeInternal(ctx, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif ev != nil {\n\t\t\tif err := changed(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\tev = v\n\t\t}\n\t\tvar sk string\n\t\t// Merge the nested map of the insert directive\n\t\tif k.Decode(&sk) == nil && insertDirective.MatchString(sk) {\n\t\t\tif ev.Kind != yaml.MappingNode {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to insert node %v into mapping %v unexpected type %v expected MappingNode\", ev, node, ev.Kind)\n\t\t\t}\n\t\t\tif err := changed(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tret.Content = append(ret.Content, ev.Content...)\n\t\t} else {\n\t\t\tek, err := ee.evaluateYamlNodeInternal(ctx, k)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif ek != nil {\n\t\t\t\tif err := changed(); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tek = k\n\t\t\t}\n\t\t\tif ret != nil {\n\t\t\t\tret.Content = append(ret.Content, ek, ev)\n\t\t\t}\n\t\t}\n\t}\n\treturn ret, nil\n}\n\nfunc (ee expressionEvaluator) evaluateSequenceYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {\n\tvar ret *yaml.Node\n\tfor i := 0; i < len(node.Content); i++ {\n\t\tv := node.Content[i]\n\t\t// Preserve nested sequences\n\t\twasseq := v.Kind == yaml.SequenceNode\n\t\tev, err := ee.evaluateYamlNodeInternal(ctx, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif ev != nil {\n\t\t\tif ret == nil {\n\t\t\t\tret = &yaml.Node{}\n\t\t\t\tif err := ret.Encode(node); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tret.Content = ret.Content[:i]\n\t\t\t}\n\t\t\t// GitHub has this undocumented feature to merge sequences / arrays\n\t\t\t// We have a nested sequence via evaluation, merge the arrays\n\t\t\tif ev.Kind == yaml.SequenceNode && !wasseq {\n\t\t\t\tret.Content = append(ret.Content, ev.Content...)\n\t\t\t} else {\n\t\t\t\tret.Content = append(ret.Content, ev)\n\t\t\t}\n\t\t} else if ret != nil {\n\t\t\tret.Content = append(ret.Content, v)\n\t\t}\n\t}\n\treturn ret, nil\n}\n\nfunc (ee expressionEvaluator) evaluateYamlNodeInternal(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {\n\tswitch node.Kind {\n\tcase yaml.ScalarNode:\n\t\treturn ee.evaluateScalarYamlNode(ctx, node)\n\tcase yaml.MappingNode:\n\t\treturn ee.evaluateMappingYamlNode(ctx, node)\n\tcase yaml.SequenceNode:\n\t\treturn ee.evaluateSequenceYamlNode(ctx, node)\n\tdefault:\n\t\treturn nil, nil\n\t}\n}\n\nfunc (ee expressionEvaluator) EvaluateYamlNode(ctx context.Context, node *yaml.Node) error {\n\tret, err := ee.evaluateYamlNodeInternal(ctx, node)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif ret != nil {\n\t\treturn ret.Decode(node)\n\t}\n\treturn nil\n}\n\nfunc (ee expressionEvaluator) Interpolate(ctx context.Context, in string) string {\n\tif !strings.Contains(in, \"${{\") || !strings.Contains(in, \"}}\") {\n\t\treturn in\n\t}\n\n\texpr, _ := rewriteSubExpression(ctx, in, true)\n\tevaluated, err := ee.evaluate(ctx, expr, exprparser.DefaultStatusCheckNone)\n\tif err != nil {\n\t\tcommon.Logger(ctx).Errorf(\"Unable to interpolate expression '%s': %s\", expr, err)\n\t\treturn \"\"\n\t}\n\n\tvalue, ok := evaluated.(string)\n\tif !ok {\n\t\tpanic(fmt.Sprintf(\"Expression %s did not evaluate to a string\", expr))\n\t}\n\n\treturn value\n}\n\n// EvalBool evaluates an expression against given evaluator\nfunc EvalBool(ctx context.Context, evaluator ExpressionEvaluator, expr string, defaultStatusCheck exprparser.DefaultStatusCheck) (bool, error) {\n\tnextExpr, _ := rewriteSubExpression(ctx, expr, false)\n\n\tevaluated, err := evaluator.evaluate(ctx, nextExpr, defaultStatusCheck)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\treturn exprparser.IsTruthy(evaluated), nil\n}\n\nfunc escapeFormatString(in string) string {\n\treturn strings.ReplaceAll(strings.ReplaceAll(in, \"{\", \"{{\"), \"}\", \"}}\")\n}\n\nfunc rewriteSubExpression(ctx context.Context, in string, forceFormat bool) (string, error) {\n\tif !strings.Contains(in, \"${{\") || !strings.Contains(in, \"}}\") {\n\t\treturn in, nil\n\t}\n\n\tstrPattern := regexp.MustCompile(\"(?:''|[^'])*'\")\n\tpos := 0\n\texprStart := -1\n\tstrStart := -1\n\tvar results []string\n\tformatOut := \"\"\n\tfor pos < len(in) {\n\t\tif strStart > -1 {\n\t\t\tmatches := strPattern.FindStringIndex(in[pos:])\n\t\t\tif matches == nil {\n\t\t\t\tpanic(\"unclosed string.\")\n\t\t\t}\n\n\t\t\tstrStart = -1\n\t\t\tpos += matches[1]\n\t\t} else if exprStart > -1 {\n\t\t\texprEnd := strings.Index(in[pos:], \"}}\")\n\t\t\tstrStart = strings.Index(in[pos:], \"'\")\n\n\t\t\tif exprEnd > -1 && strStart > -1 {\n\t\t\t\tif exprEnd < strStart {\n\t\t\t\t\tstrStart = -1\n\t\t\t\t} else {\n\t\t\t\t\texprEnd = -1\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif exprEnd > -1 {\n\t\t\t\tformatOut += fmt.Sprintf(\"{%d}\", len(results))\n\t\t\t\tresults = append(results, strings.TrimSpace(in[exprStart:pos+exprEnd]))\n\t\t\t\tpos += exprEnd + 2\n\t\t\t\texprStart = -1\n\t\t\t} else if strStart > -1 {\n\t\t\t\tpos += strStart + 1\n\t\t\t} else {\n\t\t\t\tpanic(\"unclosed expression.\")\n\t\t\t}\n\t\t} else {\n\t\t\texprStart = strings.Index(in[pos:], \"${{\")\n\t\t\tif exprStart != -1 {\n\t\t\t\tformatOut += escapeFormatString(in[pos : pos+exprStart])\n\t\t\t\texprStart = pos + exprStart + 3\n\t\t\t\tpos = exprStart\n\t\t\t} else {\n\t\t\t\tformatOut += escapeFormatString(in[pos:])\n\t\t\t\tpos = len(in)\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(results) == 1 && formatOut == \"{0}\" && !forceFormat {\n\t\treturn in, nil\n\t}\n\n\tout := fmt.Sprintf(\"format('%s', %s)\", strings.ReplaceAll(formatOut, \"'\", \"''\"), strings.Join(results, \", \"))\n\tif in != out {\n\t\tcommon.Logger(ctx).Debugf(\"expression '%s' rewritten to '%s'\", in, out)\n\t}\n\treturn out, nil\n}\n\nfunc getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *model.GithubContext) map[string]interface{} {\n\tinputs := map[string]interface{}{}\n\n\tsetupWorkflowInputs(ctx, &inputs, rc)\n\n\tvar env map[string]string\n\tif step != nil {\n\t\tenv = *step.getEnv()\n\t} else {\n\t\tenv = rc.GetEnv()\n\t}\n\n\tfor k, v := range env {\n\t\tif strings.HasPrefix(k, \"INPUT_\") {\n\t\t\tinputs[strings.ToLower(strings.TrimPrefix(k, \"INPUT_\"))] = v\n\t\t}\n\t}\n\n\tif rc.caller == nil && ghc.EventName == \"workflow_dispatch\" {\n\t\tconfig := rc.Run.Workflow.WorkflowDispatchConfig()\n\t\tif config != nil && config.Inputs != nil {\n\t\t\tfor k, v := range config.Inputs {\n\t\t\t\tvalue := nestedMapLookup(ghc.Event, \"inputs\", k)\n\t\t\t\tif value == nil {\n\t\t\t\t\tvalue = v.Default\n\t\t\t\t}\n\t\t\t\tif v.Type == \"boolean\" {\n\t\t\t\t\tinputs[k] = value == \"true\"\n\t\t\t\t} else {\n\t\t\t\t\tinputs[k] = value\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ghc.EventName == \"workflow_call\" {\n\t\tconfig := rc.Run.Workflow.WorkflowCallConfig()\n\t\tif config != nil && config.Inputs != nil {\n\t\t\tfor k, v := range config.Inputs {\n\t\t\t\tvalue := nestedMapLookup(ghc.Event, \"inputs\", k)\n\t\t\t\tif value == nil {\n\t\t\t\t\tif err := v.Default.Decode(&value); err != nil {\n\t\t\t\t\t\tcommon.Logger(ctx).Debugf(\"error decoding default value for %s: %v\", k, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif v.Type == \"boolean\" {\n\t\t\t\t\tinputs[k] = value == \"true\"\n\t\t\t\t} else {\n\t\t\t\t\tinputs[k] = value\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn inputs\n}\n\nfunc setupWorkflowInputs(ctx context.Context, inputs *map[string]interface{}, rc *RunContext) {\n\tif rc.caller != nil {\n\t\tconfig := rc.Run.Workflow.WorkflowCallConfig()\n\n\t\tfor name, input := range config.Inputs {\n\t\t\tvalue := rc.caller.runContext.Run.Job().With[name]\n\n\t\t\tif value != nil {\n\t\t\t\tnode := yaml.Node{}\n\t\t\t\t_ = node.Encode(value)\n\t\t\t\tif rc.caller.runContext.ExprEval != nil {\n\t\t\t\t\t// evaluate using the calling RunContext (outside)\n\t\t\t\t\t_ = rc.caller.runContext.ExprEval.EvaluateYamlNode(ctx, &node)\n\t\t\t\t}\n\t\t\t\t_ = node.Decode(&value)\n\t\t\t}\n\n\t\t\tif value == nil && config != nil && config.Inputs != nil {\n\t\t\t\tdef := input.Default\n\t\t\t\tif rc.ExprEval != nil {\n\t\t\t\t\t// evaluate using the called RunContext (inside)\n\t\t\t\t\t_ = rc.ExprEval.EvaluateYamlNode(ctx, &def)\n\t\t\t\t}\n\t\t\t\t_ = def.Decode(&value)\n\t\t\t}\n\n\t\t\t(*inputs)[name] = value\n\t\t}\n\t}\n}\n\nfunc getWorkflowSecrets(ctx context.Context, rc *RunContext) map[string]string {\n\tif rc.caller != nil {\n\t\tjob := rc.caller.runContext.Run.Job()\n\t\tsecrets := job.Secrets()\n\n\t\tif secrets == nil && job.InheritSecrets() {\n\t\t\tsecrets = rc.caller.runContext.Config.Secrets\n\t\t}\n\n\t\tif secrets == nil {\n\t\t\tsecrets = map[string]string{}\n\t\t}\n\n\t\tfor k, v := range secrets {\n\t\t\tsecrets[k] = rc.caller.runContext.ExprEval.Interpolate(ctx, v)\n\t\t}\n\n\t\treturn secrets\n\t}\n\n\treturn rc.Config.Secrets\n}\n\nfunc getWorkflowVars(_ context.Context, rc *RunContext) map[string]string {\n\treturn rc.Config.Vars\n}\n"
  },
  {
    "path": "pkg/runner/expression_test.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"sort\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/exprparser\"\n\t\"github.com/nektos/act/pkg/model\"\n\tassert \"github.com/stretchr/testify/assert\"\n\tyaml \"gopkg.in/yaml.v3\"\n)\n\nfunc createRunContext(t *testing.T) *RunContext {\n\tvar yml yaml.Node\n\terr := yml.Encode(map[string][]interface{}{\n\t\t\"os\":  {\"Linux\", \"Windows\"},\n\t\t\"foo\": {\"bar\", \"baz\"},\n\t})\n\tassert.NoError(t, err)\n\n\treturn &RunContext{\n\t\tConfig: &Config{\n\t\t\tWorkdir: \".\",\n\t\t\tSecrets: map[string]string{\n\t\t\t\t\"CASE_INSENSITIVE_SECRET\": \"value\",\n\t\t\t},\n\t\t\tVars: map[string]string{\n\t\t\t\t\"CASE_INSENSITIVE_VAR\": \"value\",\n\t\t\t},\n\t\t},\n\t\tEnv: map[string]string{\n\t\t\t\"key\": \"value\",\n\t\t},\n\t\tRun: &model.Run{\n\t\t\tJobID: \"job1\",\n\t\t\tWorkflow: &model.Workflow{\n\t\t\t\tName: \"test-workflow\",\n\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\"job1\": {\n\t\t\t\t\t\tStrategy: &model.Strategy{\n\t\t\t\t\t\t\tRawMatrix: yml,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tMatrix: map[string]interface{}{\n\t\t\t\"os\":  \"Linux\",\n\t\t\t\"foo\": \"bar\",\n\t\t},\n\t\tStepResults: map[string]*model.StepResult{\n\t\t\t\"idwithnothing\": {\n\t\t\t\tConclusion: model.StepStatusSuccess,\n\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\tOutputs: map[string]string{\n\t\t\t\t\t\"foowithnothing\": \"barwithnothing\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"id-with-hyphens\": {\n\t\t\t\tConclusion: model.StepStatusSuccess,\n\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\tOutputs: map[string]string{\n\t\t\t\t\t\"foo-with-hyphens\": \"bar-with-hyphens\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"id_with_underscores\": {\n\t\t\t\tConclusion: model.StepStatusSuccess,\n\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\tOutputs: map[string]string{\n\t\t\t\t\t\"foo_with_underscores\": \"bar_with_underscores\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc TestEvaluateRunContext(t *testing.T) {\n\trc := createRunContext(t)\n\tee := rc.NewExpressionEvaluator(context.Background())\n\n\ttables := []struct {\n\t\tin      string\n\t\tout     interface{}\n\t\terrMesg string\n\t}{\n\t\t{\" 1 \", 1, \"\"},\n\t\t// {\"1 + 3\", \"4\", \"\"},\n\t\t// {\"(1 + 3) * -2\", \"-8\", \"\"},\n\t\t{\"'my text'\", \"my text\", \"\"},\n\t\t{\"contains('my text', 'te')\", true, \"\"},\n\t\t{\"contains('my TEXT', 'te')\", true, \"\"},\n\t\t{\"contains(fromJSON('[\\\"my text\\\"]'), 'te')\", false, \"\"},\n\t\t{\"contains(fromJSON('[\\\"foo\\\",\\\"bar\\\"]'), 'bar')\", true, \"\"},\n\t\t{\"startsWith('hello world', 'He')\", true, \"\"},\n\t\t{\"endsWith('hello world', 'ld')\", true, \"\"},\n\t\t{\"format('0:{0} 2:{2} 1:{1}', 'zero', 'one', 'two')\", \"0:zero 2:two 1:one\", \"\"},\n\t\t{\"join(fromJSON('[\\\"hello\\\"]'),'octocat')\", \"hello\", \"\"},\n\t\t{\"join(fromJSON('[\\\"hello\\\",\\\"mona\\\",\\\"the\\\"]'),'octocat')\", \"hellooctocatmonaoctocatthe\", \"\"},\n\t\t{\"join('hello','mona')\", \"hello\", \"\"},\n\t\t{\"toJSON(env)\", \"{\\n  \\\"ACT\\\": \\\"true\\\",\\n  \\\"key\\\": \\\"value\\\"\\n}\", \"\"},\n\t\t{\"toJson(env)\", \"{\\n  \\\"ACT\\\": \\\"true\\\",\\n  \\\"key\\\": \\\"value\\\"\\n}\", \"\"},\n\t\t{\"(fromJSON('{\\\"foo\\\":\\\"bar\\\"}')).foo\", \"bar\", \"\"},\n\t\t{\"(fromJson('{\\\"foo\\\":\\\"bar\\\"}')).foo\", \"bar\", \"\"},\n\t\t{\"(fromJson('[\\\"foo\\\",\\\"bar\\\"]'))[1]\", \"bar\", \"\"},\n\t\t// github does return an empty string for non-existent files\n\t\t{\"hashFiles('**/non-extant-files')\", \"\", \"\"},\n\t\t{\"hashFiles('**/non-extant-files', '**/more-non-extant-files')\", \"\", \"\"},\n\t\t{\"hashFiles('**/non.extant.files')\", \"\", \"\"},\n\t\t{\"hashFiles('**/non''extant''files')\", \"\", \"\"},\n\t\t{\"success()\", true, \"\"},\n\t\t{\"failure()\", false, \"\"},\n\t\t{\"always()\", true, \"\"},\n\t\t{\"cancelled()\", false, \"\"},\n\t\t{\"github.workflow\", \"test-workflow\", \"\"},\n\t\t{\"github.actor\", \"nektos/act\", \"\"},\n\t\t{\"github.run_id\", \"1\", \"\"},\n\t\t{\"github.run_number\", \"1\", \"\"},\n\t\t{\"job.status\", \"success\", \"\"},\n\t\t{\"matrix.os\", \"Linux\", \"\"},\n\t\t{\"matrix.foo\", \"bar\", \"\"},\n\t\t{\"env.key\", \"value\", \"\"},\n\t\t{\"secrets.CASE_INSENSITIVE_SECRET\", \"value\", \"\"},\n\t\t{\"secrets.case_insensitive_secret\", \"value\", \"\"},\n\t\t{\"vars.CASE_INSENSITIVE_VAR\", \"value\", \"\"},\n\t\t{\"vars.case_insensitive_var\", \"value\", \"\"},\n\t\t{\"format('{{0}}', 'test')\", \"{0}\", \"\"},\n\t\t{\"format('{{{0}}}', 'test')\", \"{test}\", \"\"},\n\t\t{\"format('}}')\", \"}\", \"\"},\n\t\t{\"format('echo Hello {0} ${{Test}}', 'World')\", \"echo Hello World ${Test}\", \"\"},\n\t\t{\"format('echo Hello {0} ${{Test}}', github.undefined_property)\", \"echo Hello  ${Test}\", \"\"},\n\t\t{\"format('echo Hello {0}{1} ${{Te{0}st}}', github.undefined_property, 'World')\", \"echo Hello World ${Test}\", \"\"},\n\t\t{\"format('{0}', '{1}', 'World')\", \"{1}\", \"\"},\n\t\t{\"format('{{{0}', '{1}', 'World')\", \"{{1}\", \"\"},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.in, func(t *testing.T) {\n\t\t\tassertObject := assert.New(t)\n\t\t\tout, err := ee.evaluate(context.Background(), table.in, exprparser.DefaultStatusCheckNone)\n\t\t\tif table.errMesg == \"\" {\n\t\t\t\tassertObject.NoError(err, table.in)\n\t\t\t\tassertObject.Equal(table.out, out, table.in)\n\t\t\t} else {\n\t\t\t\tassertObject.Error(err, table.in)\n\t\t\t\tassertObject.Equal(table.errMesg, err.Error(), table.in)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestEvaluateStep(t *testing.T) {\n\trc := createRunContext(t)\n\tstep := &stepRun{\n\t\tRunContext: rc,\n\t}\n\n\tee := rc.NewStepExpressionEvaluator(context.Background(), step)\n\n\ttables := []struct {\n\t\tin      string\n\t\tout     interface{}\n\t\terrMesg string\n\t}{\n\t\t{\"steps.idwithnothing.conclusion\", model.StepStatusSuccess.String(), \"\"},\n\t\t{\"steps.idwithnothing.outcome\", model.StepStatusFailure.String(), \"\"},\n\t\t{\"steps.idwithnothing.outputs.foowithnothing\", \"barwithnothing\", \"\"},\n\t\t{\"steps.id-with-hyphens.conclusion\", model.StepStatusSuccess.String(), \"\"},\n\t\t{\"steps.id-with-hyphens.outcome\", model.StepStatusFailure.String(), \"\"},\n\t\t{\"steps.id-with-hyphens.outputs.foo-with-hyphens\", \"bar-with-hyphens\", \"\"},\n\t\t{\"steps.id_with_underscores.conclusion\", model.StepStatusSuccess.String(), \"\"},\n\t\t{\"steps.id_with_underscores.outcome\", model.StepStatusFailure.String(), \"\"},\n\t\t{\"steps.id_with_underscores.outputs.foo_with_underscores\", \"bar_with_underscores\", \"\"},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.in, func(t *testing.T) {\n\t\t\tassertObject := assert.New(t)\n\t\t\tout, err := ee.evaluate(context.Background(), table.in, exprparser.DefaultStatusCheckNone)\n\t\t\tif table.errMesg == \"\" {\n\t\t\t\tassertObject.NoError(err, table.in)\n\t\t\t\tassertObject.Equal(table.out, out, table.in)\n\t\t\t} else {\n\t\t\t\tassertObject.Error(err, table.in)\n\t\t\t\tassertObject.Equal(table.errMesg, err.Error(), table.in)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestInterpolate(t *testing.T) {\n\trc := &RunContext{\n\t\tConfig: &Config{\n\t\t\tWorkdir: \".\",\n\t\t\tSecrets: map[string]string{\n\t\t\t\t\"CASE_INSENSITIVE_SECRET\": \"value\",\n\t\t\t},\n\t\t\tVars: map[string]string{\n\t\t\t\t\"CASE_INSENSITIVE_VAR\": \"value\",\n\t\t\t},\n\t\t},\n\t\tEnv: map[string]string{\n\t\t\t\"KEYWITHNOTHING\":       \"valuewithnothing\",\n\t\t\t\"KEY-WITH-HYPHENS\":     \"value-with-hyphens\",\n\t\t\t\"KEY_WITH_UNDERSCORES\": \"value_with_underscores\",\n\t\t\t\"SOMETHING_TRUE\":       \"true\",\n\t\t\t\"SOMETHING_FALSE\":      \"false\",\n\t\t},\n\t\tRun: &model.Run{\n\t\t\tJobID: \"job1\",\n\t\t\tWorkflow: &model.Workflow{\n\t\t\t\tName: \"test-workflow\",\n\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\"job1\": {},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tee := rc.NewExpressionEvaluator(context.Background())\n\ttables := []struct {\n\t\tin  string\n\t\tout string\n\t}{\n\t\t{\" text \", \" text \"},\n\t\t{\" $text \", \" $text \"},\n\t\t{\" ${text} \", \" ${text} \"},\n\t\t{\" ${{          1                         }} to ${{2}} \", \" 1 to 2 \"},\n\t\t{\" ${{  (true || false)  }} to ${{2}} \", \" true to 2 \"},\n\t\t{\" ${{  (false   ||  '}}'  )    }} to ${{2}} \", \" }} to 2 \"},\n\t\t{\" ${{ env.KEYWITHNOTHING }} \", \" valuewithnothing \"},\n\t\t{\" ${{ env.KEY-WITH-HYPHENS }} \", \" value-with-hyphens \"},\n\t\t{\" ${{ env.KEY_WITH_UNDERSCORES }} \", \" value_with_underscores \"},\n\t\t{\"${{ secrets.CASE_INSENSITIVE_SECRET }}\", \"value\"},\n\t\t{\"${{ secrets.case_insensitive_secret }}\", \"value\"},\n\t\t{\"${{ vars.CASE_INSENSITIVE_VAR }}\", \"value\"},\n\t\t{\"${{ vars.case_insensitive_var }}\", \"value\"},\n\t\t{\"${{ env.UNKNOWN }}\", \"\"},\n\t\t{\"${{ env.SOMETHING_TRUE }}\", \"true\"},\n\t\t{\"${{ env.SOMETHING_FALSE }}\", \"false\"},\n\t\t{\"${{ !env.SOMETHING_TRUE }}\", \"false\"},\n\t\t{\"${{ !env.SOMETHING_FALSE }}\", \"false\"},\n\t\t{\"${{ !env.SOMETHING_TRUE && true }}\", \"false\"},\n\t\t{\"${{ !env.SOMETHING_FALSE && true }}\", \"false\"},\n\t\t{\"${{ env.SOMETHING_TRUE && true }}\", \"true\"},\n\t\t{\"${{ env.SOMETHING_FALSE && true }}\", \"true\"},\n\t\t{\"${{ !env.SOMETHING_TRUE || true }}\", \"true\"},\n\t\t{\"${{ !env.SOMETHING_FALSE || true }}\", \"true\"},\n\t\t{\"${{ !env.SOMETHING_TRUE && false }}\", \"false\"},\n\t\t{\"${{ !env.SOMETHING_FALSE && false }}\", \"false\"},\n\t\t{\"${{ !env.SOMETHING_TRUE || false }}\", \"false\"},\n\t\t{\"${{ !env.SOMETHING_FALSE || false }}\", \"false\"},\n\t\t{\"${{ env.SOMETHING_TRUE || false }}\", \"true\"},\n\t\t{\"${{ env.SOMETHING_FALSE || false }}\", \"false\"},\n\t\t{\"${{ env.SOMETHING_FALSE }} && ${{ env.SOMETHING_TRUE }}\", \"false && true\"},\n\t\t{\"${{ fromJSON('{}') < 2 }}\", \"false\"},\n\t}\n\n\tupdateTestExpressionWorkflow(t, tables, rc)\n\tfor _, table := range tables {\n\t\tt.Run(\"interpolate\", func(t *testing.T) {\n\t\t\tassertObject := assert.New(t)\n\t\t\tout := ee.Interpolate(context.Background(), table.in)\n\t\t\tassertObject.Equal(table.out, out, table.in)\n\t\t})\n\t}\n}\n\nfunc updateTestExpressionWorkflow(t *testing.T, tables []struct {\n\tin  string\n\tout string\n}, rc *RunContext) {\n\tvar envs string\n\tkeys := make([]string, 0, len(rc.Env))\n\tfor k := range rc.Env {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\tfor _, k := range keys {\n\t\tenvs += fmt.Sprintf(\"  %s: %s\\n\", k, rc.Env[k])\n\t}\n\n\t// editorconfig-checker-disable\n\tworkflow := fmt.Sprintf(`\nname: \"Test how expressions are handled on GitHub\"\non: push\n\nenv:\n%s\n\njobs:\n  test-espressions:\n    runs-on: ubuntu-latest\n    steps:\n`, envs)\n\t// editorconfig-checker-enable\n\tfor _, table := range tables {\n\t\texpressionPattern := regexp.MustCompile(`\\${{\\s*(.+?)\\s*}}`)\n\n\t\texpr := expressionPattern.ReplaceAllStringFunc(table.in, func(match string) string {\n\t\t\treturn fmt.Sprintf(\"€{{ %s }}\", expressionPattern.ReplaceAllString(match, \"$1\"))\n\t\t})\n\t\tname := fmt.Sprintf(`%s -> %s should be equal to %s`, expr, table.in, table.out)\n\t\techo := `run: echo \"Done \"`\n\t\tworkflow += fmt.Sprintf(\"\\n      - name: %s\\n        %s\\n\", name, echo)\n\t}\n\n\tfile, err := os.Create(\"../../.github/workflows/test-expressions.yml\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t_, err = file.WriteString(workflow)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestRewriteSubExpression(t *testing.T) {\n\ttable := []struct {\n\t\tin  string\n\t\tout string\n\t}{\n\t\t{in: \"Hello World\", out: \"Hello World\"},\n\t\t{in: \"${{ true }}\", out: \"${{ true }}\"},\n\t\t{in: \"${{ true }} ${{ true }}\", out: \"format('{0} {1}', true, true)\"},\n\t\t{in: \"${{ true || false }} ${{ true && true }}\", out: \"format('{0} {1}', true || false, true && true)\"},\n\t\t{in: \"${{ '}}' }}\", out: \"${{ '}}' }}\"},\n\t\t{in: \"${{ '''}}''' }}\", out: \"${{ '''}}''' }}\"},\n\t\t{in: \"${{ '''' }}\", out: \"${{ '''' }}\"},\n\t\t{in: `${{ fromJSON('\"}}\"') }}`, out: `${{ fromJSON('\"}}\"') }}`},\n\t\t{in: `${{ fromJSON('\"\\\"}}\\\"\"') }}`, out: `${{ fromJSON('\"\\\"}}\\\"\"') }}`},\n\t\t{in: `${{ fromJSON('\"''}}\"') }}`, out: `${{ fromJSON('\"''}}\"') }}`},\n\t\t{in: \"Hello ${{ 'World' }}\", out: \"format('Hello {0}', 'World')\"},\n\t}\n\n\tfor _, table := range table {\n\t\tt.Run(\"TestRewriteSubExpression\", func(t *testing.T) {\n\t\t\tassertObject := assert.New(t)\n\t\t\tout, err := rewriteSubExpression(context.Background(), table.in, false)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tassertObject.Equal(table.out, out, table.in)\n\t\t})\n\t}\n}\n\nfunc TestRewriteSubExpressionForceFormat(t *testing.T) {\n\ttable := []struct {\n\t\tin  string\n\t\tout string\n\t}{\n\t\t{in: \"Hello World\", out: \"Hello World\"},\n\t\t{in: \"${{ true }}\", out: \"format('{0}', true)\"},\n\t\t{in: \"${{ '}}' }}\", out: \"format('{0}', '}}')\"},\n\t\t{in: `${{ fromJSON('\"}}\"') }}`, out: `format('{0}', fromJSON('\"}}\"'))`},\n\t\t{in: \"Hello ${{ 'World' }}\", out: \"format('Hello {0}', 'World')\"},\n\t}\n\n\tfor _, table := range table {\n\t\tt.Run(\"TestRewriteSubExpressionForceFormat\", func(t *testing.T) {\n\t\t\tassertObject := assert.New(t)\n\t\t\tout, err := rewriteSubExpression(context.Background(), table.in, true)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tassertObject.Equal(table.out, out, table.in)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/hashfiles/index.js",
    "content": "/******/ (() => { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 2627:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __asyncValues = (this && this.__asyncValues) || function (o) {\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n    var m = o[Symbol.asyncIterator], i;\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n};\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n    result[\"default\"] = mod;\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst crypto = __importStar(__nccwpck_require__(6113));\nconst fs = __importStar(__nccwpck_require__(7147));\nconst glob = __importStar(__nccwpck_require__(8090));\nconst path = __importStar(__nccwpck_require__(1017));\nconst stream = __importStar(__nccwpck_require__(2781));\nconst util = __importStar(__nccwpck_require__(3837));\nfunction run() {\n    var e_1, _a;\n    return __awaiter(this, void 0, void 0, function* () {\n        // arg0 -> node\n        // arg1 -> hashFiles.js\n        // env[followSymbolicLinks] = true/null\n        // env[patterns] -> glob patterns\n        let followSymbolicLinks = false;\n        const matchPatterns = process.env.patterns || '';\n        if (process.env.followSymbolicLinks === 'true') {\n            console.log('Follow symbolic links');\n            followSymbolicLinks = true;\n        }\n        console.log(`Match Pattern: ${matchPatterns}`);\n        let hasMatch = false;\n        const githubWorkspace = process.cwd();\n        const result = crypto.createHash('sha256');\n        let count = 0;\n        const globber = yield glob.create(matchPatterns, { followSymbolicLinks });\n        try {\n            for (var _b = __asyncValues(globber.globGenerator()), _c; _c = yield _b.next(), !_c.done;) {\n                const file = _c.value;\n                console.log(file);\n                if (!file.startsWith(`${githubWorkspace}${path.sep}`)) {\n                    console.log(`Ignore '${file}' since it is not under GITHUB_WORKSPACE.`);\n                    continue;\n                }\n                if (fs.statSync(file).isDirectory()) {\n                    console.log(`Skip directory '${file}'.`);\n                    continue;\n                }\n                const hash = crypto.createHash('sha256');\n                const pipeline = util.promisify(stream.pipeline);\n                yield pipeline(fs.createReadStream(file), hash);\n                result.write(hash.digest());\n                count++;\n                if (!hasMatch) {\n                    hasMatch = true;\n                }\n            }\n        }\n        catch (e_1_1) { e_1 = { error: e_1_1 }; }\n        finally {\n            try {\n                if (_c && !_c.done && (_a = _b.return)) yield _a.call(_b);\n            }\n            finally { if (e_1) throw e_1.error; }\n        }\n        result.end();\n        if (hasMatch) {\n            console.log(`Found ${count} files to hash.`);\n            console.error(`__OUTPUT__${result.digest('hex')}__OUTPUT__`);\n        }\n        else {\n            console.error(`__OUTPUT____OUTPUT__`);\n        }\n    });\n}\nrun()\n    .then(out => {\n    console.log(out);\n    process.exit(0);\n})\n    .catch(err => {\n    console.error(err);\n    process.exit(1);\n});\n\n\n/***/ }),\n\n/***/ 7351:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.issue = exports.issueCommand = void 0;\nconst os = __importStar(__nccwpck_require__(2037));\nconst utils_1 = __nccwpck_require__(5278);\n/**\n * Commands\n *\n * Command Format:\n *   ::name key=value,key=value::message\n *\n * Examples:\n *   ::warning::This is the message\n *   ::set-env name=MY_VAR::some value\n */\nfunction issueCommand(command, properties, message) {\n    const cmd = new Command(command, properties, message);\n    process.stdout.write(cmd.toString() + os.EOL);\n}\nexports.issueCommand = issueCommand;\nfunction issue(name, message = '') {\n    issueCommand(name, {}, message);\n}\nexports.issue = issue;\nconst CMD_STRING = '::';\nclass Command {\n    constructor(command, properties, message) {\n        if (!command) {\n            command = 'missing.command';\n        }\n        this.command = command;\n        this.properties = properties;\n        this.message = message;\n    }\n    toString() {\n        let cmdStr = CMD_STRING + this.command;\n        if (this.properties && Object.keys(this.properties).length > 0) {\n            cmdStr += ' ';\n            let first = true;\n            for (const key in this.properties) {\n                if (this.properties.hasOwnProperty(key)) {\n                    const val = this.properties[key];\n                    if (val) {\n                        if (first) {\n                            first = false;\n                        }\n                        else {\n                            cmdStr += ',';\n                        }\n                        cmdStr += `${key}=${escapeProperty(val)}`;\n                    }\n                }\n            }\n        }\n        cmdStr += `${CMD_STRING}${escapeData(this.message)}`;\n        return cmdStr;\n    }\n}\nfunction escapeData(s) {\n    return utils_1.toCommandValue(s)\n        .replace(/%/g, '%25')\n        .replace(/\\r/g, '%0D')\n        .replace(/\\n/g, '%0A');\n}\nfunction escapeProperty(s) {\n    return utils_1.toCommandValue(s)\n        .replace(/%/g, '%25')\n        .replace(/\\r/g, '%0D')\n        .replace(/\\n/g, '%0A')\n        .replace(/:/g, '%3A')\n        .replace(/,/g, '%2C');\n}\n//# sourceMappingURL=command.js.map\n\n/***/ }),\n\n/***/ 2186:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;\nconst command_1 = __nccwpck_require__(7351);\nconst file_command_1 = __nccwpck_require__(717);\nconst utils_1 = __nccwpck_require__(5278);\nconst os = __importStar(__nccwpck_require__(2037));\nconst path = __importStar(__nccwpck_require__(1017));\nconst uuid_1 = __nccwpck_require__(5840);\nconst oidc_utils_1 = __nccwpck_require__(8041);\n/**\n * The code to exit an action\n */\nvar ExitCode;\n(function (ExitCode) {\n    /**\n     * A code indicating that the action was successful\n     */\n    ExitCode[ExitCode[\"Success\"] = 0] = \"Success\";\n    /**\n     * A code indicating that the action was a failure\n     */\n    ExitCode[ExitCode[\"Failure\"] = 1] = \"Failure\";\n})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));\n//-----------------------------------------------------------------------\n// Variables\n//-----------------------------------------------------------------------\n/**\n * Sets env variable for this action and future actions in the job\n * @param name the name of the variable to set\n * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction exportVariable(name, val) {\n    const convertedVal = utils_1.toCommandValue(val);\n    process.env[name] = convertedVal;\n    const filePath = process.env['GITHUB_ENV'] || '';\n    if (filePath) {\n        const delimiter = `ghadelimiter_${uuid_1.v4()}`;\n        // These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter.\n        if (name.includes(delimiter)) {\n            throw new Error(`Unexpected input: name should not contain the delimiter \"${delimiter}\"`);\n        }\n        if (convertedVal.includes(delimiter)) {\n            throw new Error(`Unexpected input: value should not contain the delimiter \"${delimiter}\"`);\n        }\n        const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;\n        file_command_1.issueCommand('ENV', commandValue);\n    }\n    else {\n        command_1.issueCommand('set-env', { name }, convertedVal);\n    }\n}\nexports.exportVariable = exportVariable;\n/**\n * Registers a secret which will get masked from logs\n * @param secret value of the secret\n */\nfunction setSecret(secret) {\n    command_1.issueCommand('add-mask', {}, secret);\n}\nexports.setSecret = setSecret;\n/**\n * Prepends inputPath to the PATH (for this action and future actions)\n * @param inputPath\n */\nfunction addPath(inputPath) {\n    const filePath = process.env['GITHUB_PATH'] || '';\n    if (filePath) {\n        file_command_1.issueCommand('PATH', inputPath);\n    }\n    else {\n        command_1.issueCommand('add-path', {}, inputPath);\n    }\n    process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;\n}\nexports.addPath = addPath;\n/**\n * Gets the value of an input.\n * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed.\n * Returns an empty string if the value is not defined.\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   string\n */\nfunction getInput(name, options) {\n    const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';\n    if (options && options.required && !val) {\n        throw new Error(`Input required and not supplied: ${name}`);\n    }\n    if (options && options.trimWhitespace === false) {\n        return val;\n    }\n    return val.trim();\n}\nexports.getInput = getInput;\n/**\n * Gets the values of an multiline input.  Each value is also trimmed.\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   string[]\n *\n */\nfunction getMultilineInput(name, options) {\n    const inputs = getInput(name, options)\n        .split('\\n')\n        .filter(x => x !== '');\n    return inputs;\n}\nexports.getMultilineInput = getMultilineInput;\n/**\n * Gets the input value of the boolean type in the YAML 1.2 \"core schema\" specification.\n * Support boolean input list: `true | True | TRUE | false | False | FALSE` .\n * The return value is also in boolean type.\n * ref: https://yaml.org/spec/1.2/spec.html#id2804923\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   boolean\n */\nfunction getBooleanInput(name, options) {\n    const trueValue = ['true', 'True', 'TRUE'];\n    const falseValue = ['false', 'False', 'FALSE'];\n    const val = getInput(name, options);\n    if (trueValue.includes(val))\n        return true;\n    if (falseValue.includes(val))\n        return false;\n    throw new TypeError(`Input does not meet YAML 1.2 \"Core Schema\" specification: ${name}\\n` +\n        `Support boolean input list: \\`true | True | TRUE | false | False | FALSE\\``);\n}\nexports.getBooleanInput = getBooleanInput;\n/**\n * Sets the value of an output.\n *\n * @param     name     name of the output to set\n * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction setOutput(name, value) {\n    process.stdout.write(os.EOL);\n    command_1.issueCommand('set-output', { name }, value);\n}\nexports.setOutput = setOutput;\n/**\n * Enables or disables the echoing of commands into stdout for the rest of the step.\n * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.\n *\n */\nfunction setCommandEcho(enabled) {\n    command_1.issue('echo', enabled ? 'on' : 'off');\n}\nexports.setCommandEcho = setCommandEcho;\n//-----------------------------------------------------------------------\n// Results\n//-----------------------------------------------------------------------\n/**\n * Sets the action status to failed.\n * When the action exits it will be with an exit code of 1\n * @param message add error issue message\n */\nfunction setFailed(message) {\n    process.exitCode = ExitCode.Failure;\n    error(message);\n}\nexports.setFailed = setFailed;\n//-----------------------------------------------------------------------\n// Logging Commands\n//-----------------------------------------------------------------------\n/**\n * Gets whether Actions Step Debug is on or not\n */\nfunction isDebug() {\n    return process.env['RUNNER_DEBUG'] === '1';\n}\nexports.isDebug = isDebug;\n/**\n * Writes debug message to user log\n * @param message debug message\n */\nfunction debug(message) {\n    command_1.issueCommand('debug', {}, message);\n}\nexports.debug = debug;\n/**\n * Adds an error issue\n * @param message error issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction error(message, properties = {}) {\n    command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.error = error;\n/**\n * Adds a warning issue\n * @param message warning issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction warning(message, properties = {}) {\n    command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.warning = warning;\n/**\n * Adds a notice issue\n * @param message notice issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction notice(message, properties = {}) {\n    command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.notice = notice;\n/**\n * Writes info to log with console.log.\n * @param message info message\n */\nfunction info(message) {\n    process.stdout.write(message + os.EOL);\n}\nexports.info = info;\n/**\n * Begin an output group.\n *\n * Output until the next `groupEnd` will be foldable in this group\n *\n * @param name The name of the output group\n */\nfunction startGroup(name) {\n    command_1.issue('group', name);\n}\nexports.startGroup = startGroup;\n/**\n * End an output group.\n */\nfunction endGroup() {\n    command_1.issue('endgroup');\n}\nexports.endGroup = endGroup;\n/**\n * Wrap an asynchronous function call in a group.\n *\n * Returns the same type as the function itself.\n *\n * @param name The name of the group\n * @param fn The function to wrap in the group\n */\nfunction group(name, fn) {\n    return __awaiter(this, void 0, void 0, function* () {\n        startGroup(name);\n        let result;\n        try {\n            result = yield fn();\n        }\n        finally {\n            endGroup();\n        }\n        return result;\n    });\n}\nexports.group = group;\n//-----------------------------------------------------------------------\n// Wrapper action state\n//-----------------------------------------------------------------------\n/**\n * Saves state for current action, the state can only be retrieved by this action's post job execution.\n *\n * @param     name     name of the state to store\n * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction saveState(name, value) {\n    command_1.issueCommand('save-state', { name }, value);\n}\nexports.saveState = saveState;\n/**\n * Gets the value of an state set by this action's main execution.\n *\n * @param     name     name of the state to get\n * @returns   string\n */\nfunction getState(name) {\n    return process.env[`STATE_${name}`] || '';\n}\nexports.getState = getState;\nfunction getIDToken(aud) {\n    return __awaiter(this, void 0, void 0, function* () {\n        return yield oidc_utils_1.OidcClient.getIDToken(aud);\n    });\n}\nexports.getIDToken = getIDToken;\n/**\n * Summary exports\n */\nvar summary_1 = __nccwpck_require__(1327);\nObject.defineProperty(exports, \"summary\", ({ enumerable: true, get: function () { return summary_1.summary; } }));\n/**\n * @deprecated use core.summary\n */\nvar summary_2 = __nccwpck_require__(1327);\nObject.defineProperty(exports, \"markdownSummary\", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } }));\n/**\n * Path exports\n */\nvar path_utils_1 = __nccwpck_require__(2981);\nObject.defineProperty(exports, \"toPosixPath\", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } }));\nObject.defineProperty(exports, \"toWin32Path\", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } }));\nObject.defineProperty(exports, \"toPlatformPath\", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } }));\n//# sourceMappingURL=core.js.map\n\n/***/ }),\n\n/***/ 717:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\n// For internal use, subject to change.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.issueCommand = void 0;\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst fs = __importStar(__nccwpck_require__(7147));\nconst os = __importStar(__nccwpck_require__(2037));\nconst utils_1 = __nccwpck_require__(5278);\nfunction issueCommand(command, message) {\n    const filePath = process.env[`GITHUB_${command}`];\n    if (!filePath) {\n        throw new Error(`Unable to find environment variable for file command ${command}`);\n    }\n    if (!fs.existsSync(filePath)) {\n        throw new Error(`Missing file at path: ${filePath}`);\n    }\n    fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {\n        encoding: 'utf8'\n    });\n}\nexports.issueCommand = issueCommand;\n//# sourceMappingURL=file-command.js.map\n\n/***/ }),\n\n/***/ 8041:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.OidcClient = void 0;\nconst http_client_1 = __nccwpck_require__(6255);\nconst auth_1 = __nccwpck_require__(5526);\nconst core_1 = __nccwpck_require__(2186);\nclass OidcClient {\n    static createHttpClient(allowRetry = true, maxRetry = 10) {\n        const requestOptions = {\n            allowRetries: allowRetry,\n            maxRetries: maxRetry\n        };\n        return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions);\n    }\n    static getRequestToken() {\n        const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'];\n        if (!token) {\n            throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable');\n        }\n        return token;\n    }\n    static getIDTokenUrl() {\n        const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL'];\n        if (!runtimeUrl) {\n            throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable');\n        }\n        return runtimeUrl;\n    }\n    static getCall(id_token_url) {\n        var _a;\n        return __awaiter(this, void 0, void 0, function* () {\n            const httpclient = OidcClient.createHttpClient();\n            const res = yield httpclient\n                .getJson(id_token_url)\n                .catch(error => {\n                throw new Error(`Failed to get ID Token. \\n\n        Error Code : ${error.statusCode}\\n\n        Error Message: ${error.result.message}`);\n            });\n            const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value;\n            if (!id_token) {\n                throw new Error('Response json body do not have ID Token field');\n            }\n            return id_token;\n        });\n    }\n    static getIDToken(audience) {\n        return __awaiter(this, void 0, void 0, function* () {\n            try {\n                // New ID Token is requested from action service\n                let id_token_url = OidcClient.getIDTokenUrl();\n                if (audience) {\n                    const encodedAudience = encodeURIComponent(audience);\n                    id_token_url = `${id_token_url}&audience=${encodedAudience}`;\n                }\n                core_1.debug(`ID token url is ${id_token_url}`);\n                const id_token = yield OidcClient.getCall(id_token_url);\n                core_1.setSecret(id_token);\n                return id_token;\n            }\n            catch (error) {\n                throw new Error(`Error message: ${error.message}`);\n            }\n        });\n    }\n}\nexports.OidcClient = OidcClient;\n//# sourceMappingURL=oidc-utils.js.map\n\n/***/ }),\n\n/***/ 2981:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0;\nconst path = __importStar(__nccwpck_require__(1017));\n/**\n * toPosixPath converts the given path to the posix form. On Windows, \\\\ will be\n * replaced with /.\n *\n * @param pth. Path to transform.\n * @return string Posix path.\n */\nfunction toPosixPath(pth) {\n    return pth.replace(/[\\\\]/g, '/');\n}\nexports.toPosixPath = toPosixPath;\n/**\n * toWin32Path converts the given path to the win32 form. On Linux, / will be\n * replaced with \\\\.\n *\n * @param pth. Path to transform.\n * @return string Win32 path.\n */\nfunction toWin32Path(pth) {\n    return pth.replace(/[/]/g, '\\\\');\n}\nexports.toWin32Path = toWin32Path;\n/**\n * toPlatformPath converts the given path to a platform-specific path. It does\n * this by replacing instances of / and \\ with the platform-specific path\n * separator.\n *\n * @param pth The path to platformize.\n * @return string The platform-specific path.\n */\nfunction toPlatformPath(pth) {\n    return pth.replace(/[/\\\\]/g, path.sep);\n}\nexports.toPlatformPath = toPlatformPath;\n//# sourceMappingURL=path-utils.js.map\n\n/***/ }),\n\n/***/ 1327:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0;\nconst os_1 = __nccwpck_require__(2037);\nconst fs_1 = __nccwpck_require__(7147);\nconst { access, appendFile, writeFile } = fs_1.promises;\nexports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY';\nexports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary';\nclass Summary {\n    constructor() {\n        this._buffer = '';\n    }\n    /**\n     * Finds the summary file path from the environment, rejects if env var is not found or file does not exist\n     * Also checks r/w permissions.\n     *\n     * @returns step summary file path\n     */\n    filePath() {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (this._filePath) {\n                return this._filePath;\n            }\n            const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR];\n            if (!pathFromEnv) {\n                throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`);\n            }\n            try {\n                yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK);\n            }\n            catch (_a) {\n                throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`);\n            }\n            this._filePath = pathFromEnv;\n            return this._filePath;\n        });\n    }\n    /**\n     * Wraps content in an HTML tag, adding any HTML attributes\n     *\n     * @param {string} tag HTML tag to wrap\n     * @param {string | null} content content within the tag\n     * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add\n     *\n     * @returns {string} content wrapped in HTML element\n     */\n    wrap(tag, content, attrs = {}) {\n        const htmlAttrs = Object.entries(attrs)\n            .map(([key, value]) => ` ${key}=\"${value}\"`)\n            .join('');\n        if (!content) {\n            return `<${tag}${htmlAttrs}>`;\n        }\n        return `<${tag}${htmlAttrs}>${content}</${tag}>`;\n    }\n    /**\n     * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default.\n     *\n     * @param {SummaryWriteOptions} [options] (optional) options for write operation\n     *\n     * @returns {Promise<Summary>} summary instance\n     */\n    write(options) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite);\n            const filePath = yield this.filePath();\n            const writeFunc = overwrite ? writeFile : appendFile;\n            yield writeFunc(filePath, this._buffer, { encoding: 'utf8' });\n            return this.emptyBuffer();\n        });\n    }\n    /**\n     * Clears the summary buffer and wipes the summary file\n     *\n     * @returns {Summary} summary instance\n     */\n    clear() {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.emptyBuffer().write({ overwrite: true });\n        });\n    }\n    /**\n     * Returns the current summary buffer as a string\n     *\n     * @returns {string} string of summary buffer\n     */\n    stringify() {\n        return this._buffer;\n    }\n    /**\n     * If the summary buffer is empty\n     *\n     * @returns {boolean} true if the buffer is empty\n     */\n    isEmptyBuffer() {\n        return this._buffer.length === 0;\n    }\n    /**\n     * Resets the summary buffer without writing to summary file\n     *\n     * @returns {Summary} summary instance\n     */\n    emptyBuffer() {\n        this._buffer = '';\n        return this;\n    }\n    /**\n     * Adds raw text to the summary buffer\n     *\n     * @param {string} text content to add\n     * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false)\n     *\n     * @returns {Summary} summary instance\n     */\n    addRaw(text, addEOL = false) {\n        this._buffer += text;\n        return addEOL ? this.addEOL() : this;\n    }\n    /**\n     * Adds the operating system-specific end-of-line marker to the buffer\n     *\n     * @returns {Summary} summary instance\n     */\n    addEOL() {\n        return this.addRaw(os_1.EOL);\n    }\n    /**\n     * Adds an HTML codeblock to the summary buffer\n     *\n     * @param {string} code content to render within fenced code block\n     * @param {string} lang (optional) language to syntax highlight code\n     *\n     * @returns {Summary} summary instance\n     */\n    addCodeBlock(code, lang) {\n        const attrs = Object.assign({}, (lang && { lang }));\n        const element = this.wrap('pre', this.wrap('code', code), attrs);\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds an HTML list to the summary buffer\n     *\n     * @param {string[]} items list of items to render\n     * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false)\n     *\n     * @returns {Summary} summary instance\n     */\n    addList(items, ordered = false) {\n        const tag = ordered ? 'ol' : 'ul';\n        const listItems = items.map(item => this.wrap('li', item)).join('');\n        const element = this.wrap(tag, listItems);\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds an HTML table to the summary buffer\n     *\n     * @param {SummaryTableCell[]} rows table rows\n     *\n     * @returns {Summary} summary instance\n     */\n    addTable(rows) {\n        const tableBody = rows\n            .map(row => {\n            const cells = row\n                .map(cell => {\n                if (typeof cell === 'string') {\n                    return this.wrap('td', cell);\n                }\n                const { header, data, colspan, rowspan } = cell;\n                const tag = header ? 'th' : 'td';\n                const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan }));\n                return this.wrap(tag, data, attrs);\n            })\n                .join('');\n            return this.wrap('tr', cells);\n        })\n            .join('');\n        const element = this.wrap('table', tableBody);\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds a collapsable HTML details element to the summary buffer\n     *\n     * @param {string} label text for the closed state\n     * @param {string} content collapsable content\n     *\n     * @returns {Summary} summary instance\n     */\n    addDetails(label, content) {\n        const element = this.wrap('details', this.wrap('summary', label) + content);\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds an HTML image tag to the summary buffer\n     *\n     * @param {string} src path to the image you to embed\n     * @param {string} alt text description of the image\n     * @param {SummaryImageOptions} options (optional) addition image attributes\n     *\n     * @returns {Summary} summary instance\n     */\n    addImage(src, alt, options) {\n        const { width, height } = options || {};\n        const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height }));\n        const element = this.wrap('img', null, Object.assign({ src, alt }, attrs));\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds an HTML section heading element\n     *\n     * @param {string} text heading text\n     * @param {number | string} [level=1] (optional) the heading level, default: 1\n     *\n     * @returns {Summary} summary instance\n     */\n    addHeading(text, level) {\n        const tag = `h${level}`;\n        const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag)\n            ? tag\n            : 'h1';\n        const element = this.wrap(allowedTag, text);\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds an HTML thematic break (<hr>) to the summary buffer\n     *\n     * @returns {Summary} summary instance\n     */\n    addSeparator() {\n        const element = this.wrap('hr', null);\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds an HTML line break (<br>) to the summary buffer\n     *\n     * @returns {Summary} summary instance\n     */\n    addBreak() {\n        const element = this.wrap('br', null);\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds an HTML blockquote to the summary buffer\n     *\n     * @param {string} text quote text\n     * @param {string} cite (optional) citation url\n     *\n     * @returns {Summary} summary instance\n     */\n    addQuote(text, cite) {\n        const attrs = Object.assign({}, (cite && { cite }));\n        const element = this.wrap('blockquote', text, attrs);\n        return this.addRaw(element).addEOL();\n    }\n    /**\n     * Adds an HTML anchor tag to the summary buffer\n     *\n     * @param {string} text link text/content\n     * @param {string} href hyperlink\n     *\n     * @returns {Summary} summary instance\n     */\n    addLink(text, href) {\n        const element = this.wrap('a', text, { href });\n        return this.addRaw(element).addEOL();\n    }\n}\nconst _summary = new Summary();\n/**\n * @deprecated use `core.summary`\n */\nexports.markdownSummary = _summary;\nexports.summary = _summary;\n//# sourceMappingURL=summary.js.map\n\n/***/ }),\n\n/***/ 5278:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.toCommandProperties = exports.toCommandValue = void 0;\n/**\n * Sanitizes an input into a string so it can be passed into issueCommand safely\n * @param input input to sanitize into a string\n */\nfunction toCommandValue(input) {\n    if (input === null || input === undefined) {\n        return '';\n    }\n    else if (typeof input === 'string' || input instanceof String) {\n        return input;\n    }\n    return JSON.stringify(input);\n}\nexports.toCommandValue = toCommandValue;\n/**\n *\n * @param annotationProperties\n * @returns The command properties to send with the actual annotation command\n * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646\n */\nfunction toCommandProperties(annotationProperties) {\n    if (!Object.keys(annotationProperties).length) {\n        return {};\n    }\n    return {\n        title: annotationProperties.title,\n        file: annotationProperties.file,\n        line: annotationProperties.startLine,\n        endLine: annotationProperties.endLine,\n        col: annotationProperties.startColumn,\n        endColumn: annotationProperties.endColumn\n    };\n}\nexports.toCommandProperties = toCommandProperties;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 8090:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst internal_globber_1 = __nccwpck_require__(8298);\n/**\n * Constructs a globber\n *\n * @param patterns  Patterns separated by newlines\n * @param options   Glob options\n */\nfunction create(patterns, options) {\n    return __awaiter(this, void 0, void 0, function* () {\n        return yield internal_globber_1.DefaultGlobber.create(patterns, options);\n    });\n}\nexports.create = create;\n//# sourceMappingURL=glob.js.map\n\n/***/ }),\n\n/***/ 1026:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst core = __nccwpck_require__(2186);\n/**\n * Returns a copy with defaults filled in.\n */\nfunction getOptions(copy) {\n    const result = {\n        followSymbolicLinks: true,\n        implicitDescendants: true,\n        omitBrokenSymbolicLinks: true\n    };\n    if (copy) {\n        if (typeof copy.followSymbolicLinks === 'boolean') {\n            result.followSymbolicLinks = copy.followSymbolicLinks;\n            core.debug(`followSymbolicLinks '${result.followSymbolicLinks}'`);\n        }\n        if (typeof copy.implicitDescendants === 'boolean') {\n            result.implicitDescendants = copy.implicitDescendants;\n            core.debug(`implicitDescendants '${result.implicitDescendants}'`);\n        }\n        if (typeof copy.omitBrokenSymbolicLinks === 'boolean') {\n            result.omitBrokenSymbolicLinks = copy.omitBrokenSymbolicLinks;\n            core.debug(`omitBrokenSymbolicLinks '${result.omitBrokenSymbolicLinks}'`);\n        }\n    }\n    return result;\n}\nexports.getOptions = getOptions;\n//# sourceMappingURL=internal-glob-options-helper.js.map\n\n/***/ }),\n\n/***/ 8298:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __asyncValues = (this && this.__asyncValues) || function (o) {\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n    var m = o[Symbol.asyncIterator], i;\n    return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n};\nvar __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }\nvar __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {\n    if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n    var g = generator.apply(thisArg, _arguments || []), i, q = [];\n    return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n    function fulfill(value) { resume(\"next\", value); }\n    function reject(value) { resume(\"throw\", value); }\n    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst core = __nccwpck_require__(2186);\nconst fs = __nccwpck_require__(7147);\nconst globOptionsHelper = __nccwpck_require__(1026);\nconst path = __nccwpck_require__(1017);\nconst patternHelper = __nccwpck_require__(9005);\nconst internal_match_kind_1 = __nccwpck_require__(1063);\nconst internal_pattern_1 = __nccwpck_require__(4536);\nconst internal_search_state_1 = __nccwpck_require__(9117);\nconst IS_WINDOWS = process.platform === 'win32';\nclass DefaultGlobber {\n    constructor(options) {\n        this.patterns = [];\n        this.searchPaths = [];\n        this.options = globOptionsHelper.getOptions(options);\n    }\n    getSearchPaths() {\n        // Return a copy\n        return this.searchPaths.slice();\n    }\n    glob() {\n        var e_1, _a;\n        return __awaiter(this, void 0, void 0, function* () {\n            const result = [];\n            try {\n                for (var _b = __asyncValues(this.globGenerator()), _c; _c = yield _b.next(), !_c.done;) {\n                    const itemPath = _c.value;\n                    result.push(itemPath);\n                }\n            }\n            catch (e_1_1) { e_1 = { error: e_1_1 }; }\n            finally {\n                try {\n                    if (_c && !_c.done && (_a = _b.return)) yield _a.call(_b);\n                }\n                finally { if (e_1) throw e_1.error; }\n            }\n            return result;\n        });\n    }\n    globGenerator() {\n        return __asyncGenerator(this, arguments, function* globGenerator_1() {\n            // Fill in defaults options\n            const options = globOptionsHelper.getOptions(this.options);\n            // Implicit descendants?\n            const patterns = [];\n            for (const pattern of this.patterns) {\n                patterns.push(pattern);\n                if (options.implicitDescendants &&\n                    (pattern.trailingSeparator ||\n                        pattern.segments[pattern.segments.length - 1] !== '**')) {\n                    patterns.push(new internal_pattern_1.Pattern(pattern.negate, pattern.segments.concat('**')));\n                }\n            }\n            // Push the search paths\n            const stack = [];\n            for (const searchPath of patternHelper.getSearchPaths(patterns)) {\n                core.debug(`Search path '${searchPath}'`);\n                // Exists?\n                try {\n                    // Intentionally using lstat. Detection for broken symlink\n                    // will be performed later (if following symlinks).\n                    yield __await(fs.promises.lstat(searchPath));\n                }\n                catch (err) {\n                    if (err.code === 'ENOENT') {\n                        continue;\n                    }\n                    throw err;\n                }\n                stack.unshift(new internal_search_state_1.SearchState(searchPath, 1));\n            }\n            // Search\n            const traversalChain = []; // used to detect cycles\n            while (stack.length) {\n                // Pop\n                const item = stack.pop();\n                // Match?\n                const match = patternHelper.match(patterns, item.path);\n                const partialMatch = !!match || patternHelper.partialMatch(patterns, item.path);\n                if (!match && !partialMatch) {\n                    continue;\n                }\n                // Stat\n                const stats = yield __await(DefaultGlobber.stat(item, options, traversalChain)\n                // Broken symlink, or symlink cycle detected, or no longer exists\n                );\n                // Broken symlink, or symlink cycle detected, or no longer exists\n                if (!stats) {\n                    continue;\n                }\n                // Directory\n                if (stats.isDirectory()) {\n                    // Matched\n                    if (match & internal_match_kind_1.MatchKind.Directory) {\n                        yield yield __await(item.path);\n                    }\n                    // Descend?\n                    else if (!partialMatch) {\n                        continue;\n                    }\n                    // Push the child items in reverse\n                    const childLevel = item.level + 1;\n                    const childItems = (yield __await(fs.promises.readdir(item.path))).map(x => new internal_search_state_1.SearchState(path.join(item.path, x), childLevel));\n                    stack.push(...childItems.reverse());\n                }\n                // File\n                else if (match & internal_match_kind_1.MatchKind.File) {\n                    yield yield __await(item.path);\n                }\n            }\n        });\n    }\n    /**\n     * Constructs a DefaultGlobber\n     */\n    static create(patterns, options) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const result = new DefaultGlobber(options);\n            if (IS_WINDOWS) {\n                patterns = patterns.replace(/\\r\\n/g, '\\n');\n                patterns = patterns.replace(/\\r/g, '\\n');\n            }\n            const lines = patterns.split('\\n').map(x => x.trim());\n            for (const line of lines) {\n                // Empty or comment\n                if (!line || line.startsWith('#')) {\n                    continue;\n                }\n                // Pattern\n                else {\n                    result.patterns.push(new internal_pattern_1.Pattern(line));\n                }\n            }\n            result.searchPaths.push(...patternHelper.getSearchPaths(result.patterns));\n            return result;\n        });\n    }\n    static stat(item, options, traversalChain) {\n        return __awaiter(this, void 0, void 0, function* () {\n            // Note:\n            // `stat` returns info about the target of a symlink (or symlink chain)\n            // `lstat` returns info about a symlink itself\n            let stats;\n            if (options.followSymbolicLinks) {\n                try {\n                    // Use `stat` (following symlinks)\n                    stats = yield fs.promises.stat(item.path);\n                }\n                catch (err) {\n                    if (err.code === 'ENOENT') {\n                        if (options.omitBrokenSymbolicLinks) {\n                            core.debug(`Broken symlink '${item.path}'`);\n                            return undefined;\n                        }\n                        throw new Error(`No information found for the path '${item.path}'. This may indicate a broken symbolic link.`);\n                    }\n                    throw err;\n                }\n            }\n            else {\n                // Use `lstat` (not following symlinks)\n                stats = yield fs.promises.lstat(item.path);\n            }\n            // Note, isDirectory() returns false for the lstat of a symlink\n            if (stats.isDirectory() && options.followSymbolicLinks) {\n                // Get the realpath\n                const realPath = yield fs.promises.realpath(item.path);\n                // Fixup the traversal chain to match the item level\n                while (traversalChain.length >= item.level) {\n                    traversalChain.pop();\n                }\n                // Test for a cycle\n                if (traversalChain.some((x) => x === realPath)) {\n                    core.debug(`Symlink cycle detected for path '${item.path}' and realpath '${realPath}'`);\n                    return undefined;\n                }\n                // Update the traversal chain\n                traversalChain.push(realPath);\n            }\n            return stats;\n        });\n    }\n}\nexports.DefaultGlobber = DefaultGlobber;\n//# sourceMappingURL=internal-globber.js.map\n\n/***/ }),\n\n/***/ 1063:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/**\n * Indicates whether a pattern matches a path\n */\nvar MatchKind;\n(function (MatchKind) {\n    /** Not matched */\n    MatchKind[MatchKind[\"None\"] = 0] = \"None\";\n    /** Matched if the path is a directory */\n    MatchKind[MatchKind[\"Directory\"] = 1] = \"Directory\";\n    /** Matched if the path is a regular file */\n    MatchKind[MatchKind[\"File\"] = 2] = \"File\";\n    /** Matched */\n    MatchKind[MatchKind[\"All\"] = 3] = \"All\";\n})(MatchKind = exports.MatchKind || (exports.MatchKind = {}));\n//# sourceMappingURL=internal-match-kind.js.map\n\n/***/ }),\n\n/***/ 1849:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst assert = __nccwpck_require__(9491);\nconst path = __nccwpck_require__(1017);\nconst IS_WINDOWS = process.platform === 'win32';\n/**\n * Similar to path.dirname except normalizes the path separators and slightly better handling for Windows UNC paths.\n *\n * For example, on Linux/macOS:\n * - `/               => /`\n * - `/hello          => /`\n *\n * For example, on Windows:\n * - `C:\\             => C:\\`\n * - `C:\\hello        => C:\\`\n * - `C:              => C:`\n * - `C:hello         => C:`\n * - `\\               => \\`\n * - `\\hello          => \\`\n * - `\\\\hello         => \\\\hello`\n * - `\\\\hello\\world   => \\\\hello\\world`\n */\nfunction dirname(p) {\n    // Normalize slashes and trim unnecessary trailing slash\n    p = safeTrimTrailingSeparator(p);\n    // Windows UNC root, e.g. \\\\hello or \\\\hello\\world\n    if (IS_WINDOWS && /^\\\\\\\\[^\\\\]+(\\\\[^\\\\]+)?$/.test(p)) {\n        return p;\n    }\n    // Get dirname\n    let result = path.dirname(p);\n    // Trim trailing slash for Windows UNC root, e.g. \\\\hello\\world\\\n    if (IS_WINDOWS && /^\\\\\\\\[^\\\\]+\\\\[^\\\\]+\\\\$/.test(result)) {\n        result = safeTrimTrailingSeparator(result);\n    }\n    return result;\n}\nexports.dirname = dirname;\n/**\n * Roots the path if not already rooted. On Windows, relative roots like `\\`\n * or `C:` are expanded based on the current working directory.\n */\nfunction ensureAbsoluteRoot(root, itemPath) {\n    assert(root, `ensureAbsoluteRoot parameter 'root' must not be empty`);\n    assert(itemPath, `ensureAbsoluteRoot parameter 'itemPath' must not be empty`);\n    // Already rooted\n    if (hasAbsoluteRoot(itemPath)) {\n        return itemPath;\n    }\n    // Windows\n    if (IS_WINDOWS) {\n        // Check for itemPath like C: or C:foo\n        if (itemPath.match(/^[A-Z]:[^\\\\/]|^[A-Z]:$/i)) {\n            let cwd = process.cwd();\n            assert(cwd.match(/^[A-Z]:\\\\/i), `Expected current directory to start with an absolute drive root. Actual '${cwd}'`);\n            // Drive letter matches cwd? Expand to cwd\n            if (itemPath[0].toUpperCase() === cwd[0].toUpperCase()) {\n                // Drive only, e.g. C:\n                if (itemPath.length === 2) {\n                    // Preserve specified drive letter case (upper or lower)\n                    return `${itemPath[0]}:\\\\${cwd.substr(3)}`;\n                }\n                // Drive + path, e.g. C:foo\n                else {\n                    if (!cwd.endsWith('\\\\')) {\n                        cwd += '\\\\';\n                    }\n                    // Preserve specified drive letter case (upper or lower)\n                    return `${itemPath[0]}:\\\\${cwd.substr(3)}${itemPath.substr(2)}`;\n                }\n            }\n            // Different drive\n            else {\n                return `${itemPath[0]}:\\\\${itemPath.substr(2)}`;\n            }\n        }\n        // Check for itemPath like \\ or \\foo\n        else if (normalizeSeparators(itemPath).match(/^\\\\$|^\\\\[^\\\\]/)) {\n            const cwd = process.cwd();\n            assert(cwd.match(/^[A-Z]:\\\\/i), `Expected current directory to start with an absolute drive root. Actual '${cwd}'`);\n            return `${cwd[0]}:\\\\${itemPath.substr(1)}`;\n        }\n    }\n    assert(hasAbsoluteRoot(root), `ensureAbsoluteRoot parameter 'root' must have an absolute root`);\n    // Otherwise ensure root ends with a separator\n    if (root.endsWith('/') || (IS_WINDOWS && root.endsWith('\\\\'))) {\n        // Intentionally empty\n    }\n    else {\n        // Append separator\n        root += path.sep;\n    }\n    return root + itemPath;\n}\nexports.ensureAbsoluteRoot = ensureAbsoluteRoot;\n/**\n * On Linux/macOS, true if path starts with `/`. On Windows, true for paths like:\n * `\\\\hello\\share` and `C:\\hello` (and using alternate separator).\n */\nfunction hasAbsoluteRoot(itemPath) {\n    assert(itemPath, `hasAbsoluteRoot parameter 'itemPath' must not be empty`);\n    // Normalize separators\n    itemPath = normalizeSeparators(itemPath);\n    // Windows\n    if (IS_WINDOWS) {\n        // E.g. \\\\hello\\share or C:\\hello\n        return itemPath.startsWith('\\\\\\\\') || /^[A-Z]:\\\\/i.test(itemPath);\n    }\n    // E.g. /hello\n    return itemPath.startsWith('/');\n}\nexports.hasAbsoluteRoot = hasAbsoluteRoot;\n/**\n * On Linux/macOS, true if path starts with `/`. On Windows, true for paths like:\n * `\\`, `\\hello`, `\\\\hello\\share`, `C:`, and `C:\\hello` (and using alternate separator).\n */\nfunction hasRoot(itemPath) {\n    assert(itemPath, `isRooted parameter 'itemPath' must not be empty`);\n    // Normalize separators\n    itemPath = normalizeSeparators(itemPath);\n    // Windows\n    if (IS_WINDOWS) {\n        // E.g. \\ or \\hello or \\\\hello\n        // E.g. C: or C:\\hello\n        return itemPath.startsWith('\\\\') || /^[A-Z]:/i.test(itemPath);\n    }\n    // E.g. /hello\n    return itemPath.startsWith('/');\n}\nexports.hasRoot = hasRoot;\n/**\n * Removes redundant slashes and converts `/` to `\\` on Windows\n */\nfunction normalizeSeparators(p) {\n    p = p || '';\n    // Windows\n    if (IS_WINDOWS) {\n        // Convert slashes on Windows\n        p = p.replace(/\\//g, '\\\\');\n        // Remove redundant slashes\n        const isUnc = /^\\\\\\\\+[^\\\\]/.test(p); // e.g. \\\\hello\n        return (isUnc ? '\\\\' : '') + p.replace(/\\\\\\\\+/g, '\\\\'); // preserve leading \\\\ for UNC\n    }\n    // Remove redundant slashes\n    return p.replace(/\\/\\/+/g, '/');\n}\nexports.normalizeSeparators = normalizeSeparators;\n/**\n * Normalizes the path separators and trims the trailing separator (when safe).\n * For example, `/foo/ => /foo` but `/ => /`\n */\nfunction safeTrimTrailingSeparator(p) {\n    // Short-circuit if empty\n    if (!p) {\n        return '';\n    }\n    // Normalize separators\n    p = normalizeSeparators(p);\n    // No trailing slash\n    if (!p.endsWith(path.sep)) {\n        return p;\n    }\n    // Check '/' on Linux/macOS and '\\' on Windows\n    if (p === path.sep) {\n        return p;\n    }\n    // On Windows check if drive root. E.g. C:\\\n    if (IS_WINDOWS && /^[A-Z]:\\\\$/i.test(p)) {\n        return p;\n    }\n    // Otherwise trim trailing slash\n    return p.substr(0, p.length - 1);\n}\nexports.safeTrimTrailingSeparator = safeTrimTrailingSeparator;\n//# sourceMappingURL=internal-path-helper.js.map\n\n/***/ }),\n\n/***/ 6836:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst assert = __nccwpck_require__(9491);\nconst path = __nccwpck_require__(1017);\nconst pathHelper = __nccwpck_require__(1849);\nconst IS_WINDOWS = process.platform === 'win32';\n/**\n * Helper class for parsing paths into segments\n */\nclass Path {\n    /**\n     * Constructs a Path\n     * @param itemPath Path or array of segments\n     */\n    constructor(itemPath) {\n        this.segments = [];\n        // String\n        if (typeof itemPath === 'string') {\n            assert(itemPath, `Parameter 'itemPath' must not be empty`);\n            // Normalize slashes and trim unnecessary trailing slash\n            itemPath = pathHelper.safeTrimTrailingSeparator(itemPath);\n            // Not rooted\n            if (!pathHelper.hasRoot(itemPath)) {\n                this.segments = itemPath.split(path.sep);\n            }\n            // Rooted\n            else {\n                // Add all segments, while not at the root\n                let remaining = itemPath;\n                let dir = pathHelper.dirname(remaining);\n                while (dir !== remaining) {\n                    // Add the segment\n                    const basename = path.basename(remaining);\n                    this.segments.unshift(basename);\n                    // Truncate the last segment\n                    remaining = dir;\n                    dir = pathHelper.dirname(remaining);\n                }\n                // Remainder is the root\n                this.segments.unshift(remaining);\n            }\n        }\n        // Array\n        else {\n            // Must not be empty\n            assert(itemPath.length > 0, `Parameter 'itemPath' must not be an empty array`);\n            // Each segment\n            for (let i = 0; i < itemPath.length; i++) {\n                let segment = itemPath[i];\n                // Must not be empty\n                assert(segment, `Parameter 'itemPath' must not contain any empty segments`);\n                // Normalize slashes\n                segment = pathHelper.normalizeSeparators(itemPath[i]);\n                // Root segment\n                if (i === 0 && pathHelper.hasRoot(segment)) {\n                    segment = pathHelper.safeTrimTrailingSeparator(segment);\n                    assert(segment === pathHelper.dirname(segment), `Parameter 'itemPath' root segment contains information for multiple segments`);\n                    this.segments.push(segment);\n                }\n                // All other segments\n                else {\n                    // Must not contain slash\n                    assert(!segment.includes(path.sep), `Parameter 'itemPath' contains unexpected path separators`);\n                    this.segments.push(segment);\n                }\n            }\n        }\n    }\n    /**\n     * Converts the path to it's string representation\n     */\n    toString() {\n        // First segment\n        let result = this.segments[0];\n        // All others\n        let skipSlash = result.endsWith(path.sep) || (IS_WINDOWS && /^[A-Z]:$/i.test(result));\n        for (let i = 1; i < this.segments.length; i++) {\n            if (skipSlash) {\n                skipSlash = false;\n            }\n            else {\n                result += path.sep;\n            }\n            result += this.segments[i];\n        }\n        return result;\n    }\n}\nexports.Path = Path;\n//# sourceMappingURL=internal-path.js.map\n\n/***/ }),\n\n/***/ 9005:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst pathHelper = __nccwpck_require__(1849);\nconst internal_match_kind_1 = __nccwpck_require__(1063);\nconst IS_WINDOWS = process.platform === 'win32';\n/**\n * Given an array of patterns, returns an array of paths to search.\n * Duplicates and paths under other included paths are filtered out.\n */\nfunction getSearchPaths(patterns) {\n    // Ignore negate patterns\n    patterns = patterns.filter(x => !x.negate);\n    // Create a map of all search paths\n    const searchPathMap = {};\n    for (const pattern of patterns) {\n        const key = IS_WINDOWS\n            ? pattern.searchPath.toUpperCase()\n            : pattern.searchPath;\n        searchPathMap[key] = 'candidate';\n    }\n    const result = [];\n    for (const pattern of patterns) {\n        // Check if already included\n        const key = IS_WINDOWS\n            ? pattern.searchPath.toUpperCase()\n            : pattern.searchPath;\n        if (searchPathMap[key] === 'included') {\n            continue;\n        }\n        // Check for an ancestor search path\n        let foundAncestor = false;\n        let tempKey = key;\n        let parent = pathHelper.dirname(tempKey);\n        while (parent !== tempKey) {\n            if (searchPathMap[parent]) {\n                foundAncestor = true;\n                break;\n            }\n            tempKey = parent;\n            parent = pathHelper.dirname(tempKey);\n        }\n        // Include the search pattern in the result\n        if (!foundAncestor) {\n            result.push(pattern.searchPath);\n            searchPathMap[key] = 'included';\n        }\n    }\n    return result;\n}\nexports.getSearchPaths = getSearchPaths;\n/**\n * Matches the patterns against the path\n */\nfunction match(patterns, itemPath) {\n    let result = internal_match_kind_1.MatchKind.None;\n    for (const pattern of patterns) {\n        if (pattern.negate) {\n            result &= ~pattern.match(itemPath);\n        }\n        else {\n            result |= pattern.match(itemPath);\n        }\n    }\n    return result;\n}\nexports.match = match;\n/**\n * Checks whether to descend further into the directory\n */\nfunction partialMatch(patterns, itemPath) {\n    return patterns.some(x => !x.negate && x.partialMatch(itemPath));\n}\nexports.partialMatch = partialMatch;\n//# sourceMappingURL=internal-pattern-helper.js.map\n\n/***/ }),\n\n/***/ 4536:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst assert = __nccwpck_require__(9491);\nconst os = __nccwpck_require__(2037);\nconst path = __nccwpck_require__(1017);\nconst pathHelper = __nccwpck_require__(1849);\nconst minimatch_1 = __nccwpck_require__(3973);\nconst internal_match_kind_1 = __nccwpck_require__(1063);\nconst internal_path_1 = __nccwpck_require__(6836);\nconst IS_WINDOWS = process.platform === 'win32';\nclass Pattern {\n    constructor(patternOrNegate, segments) {\n        /**\n         * Indicates whether matches should be excluded from the result set\n         */\n        this.negate = false;\n        // Pattern overload\n        let pattern;\n        if (typeof patternOrNegate === 'string') {\n            pattern = patternOrNegate.trim();\n        }\n        // Segments overload\n        else {\n            // Convert to pattern\n            segments = segments || [];\n            assert(segments.length, `Parameter 'segments' must not empty`);\n            const root = Pattern.getLiteral(segments[0]);\n            assert(root && pathHelper.hasAbsoluteRoot(root), `Parameter 'segments' first element must be a root path`);\n            pattern = new internal_path_1.Path(segments).toString().trim();\n            if (patternOrNegate) {\n                pattern = `!${pattern}`;\n            }\n        }\n        // Negate\n        while (pattern.startsWith('!')) {\n            this.negate = !this.negate;\n            pattern = pattern.substr(1).trim();\n        }\n        // Normalize slashes and ensures absolute root\n        pattern = Pattern.fixupPattern(pattern);\n        // Segments\n        this.segments = new internal_path_1.Path(pattern).segments;\n        // Trailing slash indicates the pattern should only match directories, not regular files\n        this.trailingSeparator = pathHelper\n            .normalizeSeparators(pattern)\n            .endsWith(path.sep);\n        pattern = pathHelper.safeTrimTrailingSeparator(pattern);\n        // Search path (literal path prior to the first glob segment)\n        let foundGlob = false;\n        const searchSegments = this.segments\n            .map(x => Pattern.getLiteral(x))\n            .filter(x => !foundGlob && !(foundGlob = x === ''));\n        this.searchPath = new internal_path_1.Path(searchSegments).toString();\n        // Root RegExp (required when determining partial match)\n        this.rootRegExp = new RegExp(Pattern.regExpEscape(searchSegments[0]), IS_WINDOWS ? 'i' : '');\n        // Create minimatch\n        const minimatchOptions = {\n            dot: true,\n            nobrace: true,\n            nocase: IS_WINDOWS,\n            nocomment: true,\n            noext: true,\n            nonegate: true\n        };\n        pattern = IS_WINDOWS ? pattern.replace(/\\\\/g, '/') : pattern;\n        this.minimatch = new minimatch_1.Minimatch(pattern, minimatchOptions);\n    }\n    /**\n     * Matches the pattern against the specified path\n     */\n    match(itemPath) {\n        // Last segment is globstar?\n        if (this.segments[this.segments.length - 1] === '**') {\n            // Normalize slashes\n            itemPath = pathHelper.normalizeSeparators(itemPath);\n            // Append a trailing slash. Otherwise Minimatch will not match the directory immediately\n            // preceding the globstar. For example, given the pattern `/foo/**`, Minimatch returns\n            // false for `/foo` but returns true for `/foo/`. Append a trailing slash to handle that quirk.\n            if (!itemPath.endsWith(path.sep)) {\n                // Note, this is safe because the constructor ensures the pattern has an absolute root.\n                // For example, formats like C: and C:foo on Windows are resolved to an aboslute root.\n                itemPath = `${itemPath}${path.sep}`;\n            }\n        }\n        else {\n            // Normalize slashes and trim unnecessary trailing slash\n            itemPath = pathHelper.safeTrimTrailingSeparator(itemPath);\n        }\n        // Match\n        if (this.minimatch.match(itemPath)) {\n            return this.trailingSeparator ? internal_match_kind_1.MatchKind.Directory : internal_match_kind_1.MatchKind.All;\n        }\n        return internal_match_kind_1.MatchKind.None;\n    }\n    /**\n     * Indicates whether the pattern may match descendants of the specified path\n     */\n    partialMatch(itemPath) {\n        // Normalize slashes and trim unnecessary trailing slash\n        itemPath = pathHelper.safeTrimTrailingSeparator(itemPath);\n        // matchOne does not handle root path correctly\n        if (pathHelper.dirname(itemPath) === itemPath) {\n            return this.rootRegExp.test(itemPath);\n        }\n        return this.minimatch.matchOne(itemPath.split(IS_WINDOWS ? /\\\\+/ : /\\/+/), this.minimatch.set[0], true);\n    }\n    /**\n     * Escapes glob patterns within a path\n     */\n    static globEscape(s) {\n        return (IS_WINDOWS ? s : s.replace(/\\\\/g, '\\\\\\\\')) // escape '\\' on Linux/macOS\n            .replace(/(\\[)(?=[^/]+\\])/g, '[[]') // escape '[' when ']' follows within the path segment\n            .replace(/\\?/g, '[?]') // escape '?'\n            .replace(/\\*/g, '[*]'); // escape '*'\n    }\n    /**\n     * Normalizes slashes and ensures absolute root\n     */\n    static fixupPattern(pattern) {\n        // Empty\n        assert(pattern, 'pattern cannot be empty');\n        // Must not contain `.` segment, unless first segment\n        // Must not contain `..` segment\n        const literalSegments = new internal_path_1.Path(pattern).segments.map(x => Pattern.getLiteral(x));\n        assert(literalSegments.every((x, i) => (x !== '.' || i === 0) && x !== '..'), `Invalid pattern '${pattern}'. Relative pathing '.' and '..' is not allowed.`);\n        // Must not contain globs in root, e.g. Windows UNC path \\\\foo\\b*r\n        assert(!pathHelper.hasRoot(pattern) || literalSegments[0], `Invalid pattern '${pattern}'. Root segment must not contain globs.`);\n        // Normalize slashes\n        pattern = pathHelper.normalizeSeparators(pattern);\n        // Replace leading `.` segment\n        if (pattern === '.' || pattern.startsWith(`.${path.sep}`)) {\n            pattern = Pattern.globEscape(process.cwd()) + pattern.substr(1);\n        }\n        // Replace leading `~` segment\n        else if (pattern === '~' || pattern.startsWith(`~${path.sep}`)) {\n            const homedir = os.homedir();\n            assert(homedir, 'Unable to determine HOME directory');\n            assert(pathHelper.hasAbsoluteRoot(homedir), `Expected HOME directory to be a rooted path. Actual '${homedir}'`);\n            pattern = Pattern.globEscape(homedir) + pattern.substr(1);\n        }\n        // Replace relative drive root, e.g. pattern is C: or C:foo\n        else if (IS_WINDOWS &&\n            (pattern.match(/^[A-Z]:$/i) || pattern.match(/^[A-Z]:[^\\\\]/i))) {\n            let root = pathHelper.ensureAbsoluteRoot('C:\\\\dummy-root', pattern.substr(0, 2));\n            if (pattern.length > 2 && !root.endsWith('\\\\')) {\n                root += '\\\\';\n            }\n            pattern = Pattern.globEscape(root) + pattern.substr(2);\n        }\n        // Replace relative root, e.g. pattern is \\ or \\foo\n        else if (IS_WINDOWS && (pattern === '\\\\' || pattern.match(/^\\\\[^\\\\]/))) {\n            let root = pathHelper.ensureAbsoluteRoot('C:\\\\dummy-root', '\\\\');\n            if (!root.endsWith('\\\\')) {\n                root += '\\\\';\n            }\n            pattern = Pattern.globEscape(root) + pattern.substr(1);\n        }\n        // Otherwise ensure absolute root\n        else {\n            pattern = pathHelper.ensureAbsoluteRoot(Pattern.globEscape(process.cwd()), pattern);\n        }\n        return pathHelper.normalizeSeparators(pattern);\n    }\n    /**\n     * Attempts to unescape a pattern segment to create a literal path segment.\n     * Otherwise returns empty string.\n     */\n    static getLiteral(segment) {\n        let literal = '';\n        for (let i = 0; i < segment.length; i++) {\n            const c = segment[i];\n            // Escape\n            if (c === '\\\\' && !IS_WINDOWS && i + 1 < segment.length) {\n                literal += segment[++i];\n                continue;\n            }\n            // Wildcard\n            else if (c === '*' || c === '?') {\n                return '';\n            }\n            // Character set\n            else if (c === '[' && i + 1 < segment.length) {\n                let set = '';\n                let closed = -1;\n                for (let i2 = i + 1; i2 < segment.length; i2++) {\n                    const c2 = segment[i2];\n                    // Escape\n                    if (c2 === '\\\\' && !IS_WINDOWS && i2 + 1 < segment.length) {\n                        set += segment[++i2];\n                        continue;\n                    }\n                    // Closed\n                    else if (c2 === ']') {\n                        closed = i2;\n                        break;\n                    }\n                    // Otherwise\n                    else {\n                        set += c2;\n                    }\n                }\n                // Closed?\n                if (closed >= 0) {\n                    // Cannot convert\n                    if (set.length > 1) {\n                        return '';\n                    }\n                    // Convert to literal\n                    if (set) {\n                        literal += set;\n                        i = closed;\n                        continue;\n                    }\n                }\n                // Otherwise fall thru\n            }\n            // Append\n            literal += c;\n        }\n        return literal;\n    }\n    /**\n     * Escapes regexp special characters\n     * https://javascript.info/regexp-escaping\n     */\n    static regExpEscape(s) {\n        return s.replace(/[[\\\\^$.|?*+()]/g, '\\\\$&');\n    }\n}\nexports.Pattern = Pattern;\n//# sourceMappingURL=internal-pattern.js.map\n\n/***/ }),\n\n/***/ 9117:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nclass SearchState {\n    constructor(path, level) {\n        this.path = path;\n        this.level = level;\n    }\n}\nexports.SearchState = SearchState;\n//# sourceMappingURL=internal-search-state.js.map\n\n/***/ }),\n\n/***/ 5526:\n/***/ (function(__unused_webpack_module, exports) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0;\nclass BasicCredentialHandler {\n    constructor(username, password) {\n        this.username = username;\n        this.password = password;\n    }\n    prepareRequest(options) {\n        if (!options.headers) {\n            throw Error('The request has no headers');\n        }\n        options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`;\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication() {\n        return false;\n    }\n    handleAuthentication() {\n        return __awaiter(this, void 0, void 0, function* () {\n            throw new Error('not implemented');\n        });\n    }\n}\nexports.BasicCredentialHandler = BasicCredentialHandler;\nclass BearerCredentialHandler {\n    constructor(token) {\n        this.token = token;\n    }\n    // currently implements pre-authorization\n    // TODO: support preAuth = false where it hooks on 401\n    prepareRequest(options) {\n        if (!options.headers) {\n            throw Error('The request has no headers');\n        }\n        options.headers['Authorization'] = `Bearer ${this.token}`;\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication() {\n        return false;\n    }\n    handleAuthentication() {\n        return __awaiter(this, void 0, void 0, function* () {\n            throw new Error('not implemented');\n        });\n    }\n}\nexports.BearerCredentialHandler = BearerCredentialHandler;\nclass PersonalAccessTokenCredentialHandler {\n    constructor(token) {\n        this.token = token;\n    }\n    // currently implements pre-authorization\n    // TODO: support preAuth = false where it hooks on 401\n    prepareRequest(options) {\n        if (!options.headers) {\n            throw Error('The request has no headers');\n        }\n        options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`;\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication() {\n        return false;\n    }\n    handleAuthentication() {\n        return __awaiter(this, void 0, void 0, function* () {\n            throw new Error('not implemented');\n        });\n    }\n}\nexports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler;\n//# sourceMappingURL=auth.js.map\n\n/***/ }),\n\n/***/ 6255:\n/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {\n\n\"use strict\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0;\nconst http = __importStar(__nccwpck_require__(3685));\nconst https = __importStar(__nccwpck_require__(5687));\nconst pm = __importStar(__nccwpck_require__(9835));\nconst tunnel = __importStar(__nccwpck_require__(4294));\nvar HttpCodes;\n(function (HttpCodes) {\n    HttpCodes[HttpCodes[\"OK\"] = 200] = \"OK\";\n    HttpCodes[HttpCodes[\"MultipleChoices\"] = 300] = \"MultipleChoices\";\n    HttpCodes[HttpCodes[\"MovedPermanently\"] = 301] = \"MovedPermanently\";\n    HttpCodes[HttpCodes[\"ResourceMoved\"] = 302] = \"ResourceMoved\";\n    HttpCodes[HttpCodes[\"SeeOther\"] = 303] = \"SeeOther\";\n    HttpCodes[HttpCodes[\"NotModified\"] = 304] = \"NotModified\";\n    HttpCodes[HttpCodes[\"UseProxy\"] = 305] = \"UseProxy\";\n    HttpCodes[HttpCodes[\"SwitchProxy\"] = 306] = \"SwitchProxy\";\n    HttpCodes[HttpCodes[\"TemporaryRedirect\"] = 307] = \"TemporaryRedirect\";\n    HttpCodes[HttpCodes[\"PermanentRedirect\"] = 308] = \"PermanentRedirect\";\n    HttpCodes[HttpCodes[\"BadRequest\"] = 400] = \"BadRequest\";\n    HttpCodes[HttpCodes[\"Unauthorized\"] = 401] = \"Unauthorized\";\n    HttpCodes[HttpCodes[\"PaymentRequired\"] = 402] = \"PaymentRequired\";\n    HttpCodes[HttpCodes[\"Forbidden\"] = 403] = \"Forbidden\";\n    HttpCodes[HttpCodes[\"NotFound\"] = 404] = \"NotFound\";\n    HttpCodes[HttpCodes[\"MethodNotAllowed\"] = 405] = \"MethodNotAllowed\";\n    HttpCodes[HttpCodes[\"NotAcceptable\"] = 406] = \"NotAcceptable\";\n    HttpCodes[HttpCodes[\"ProxyAuthenticationRequired\"] = 407] = \"ProxyAuthenticationRequired\";\n    HttpCodes[HttpCodes[\"RequestTimeout\"] = 408] = \"RequestTimeout\";\n    HttpCodes[HttpCodes[\"Conflict\"] = 409] = \"Conflict\";\n    HttpCodes[HttpCodes[\"Gone\"] = 410] = \"Gone\";\n    HttpCodes[HttpCodes[\"TooManyRequests\"] = 429] = \"TooManyRequests\";\n    HttpCodes[HttpCodes[\"InternalServerError\"] = 500] = \"InternalServerError\";\n    HttpCodes[HttpCodes[\"NotImplemented\"] = 501] = \"NotImplemented\";\n    HttpCodes[HttpCodes[\"BadGateway\"] = 502] = \"BadGateway\";\n    HttpCodes[HttpCodes[\"ServiceUnavailable\"] = 503] = \"ServiceUnavailable\";\n    HttpCodes[HttpCodes[\"GatewayTimeout\"] = 504] = \"GatewayTimeout\";\n})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));\nvar Headers;\n(function (Headers) {\n    Headers[\"Accept\"] = \"accept\";\n    Headers[\"ContentType\"] = \"content-type\";\n})(Headers = exports.Headers || (exports.Headers = {}));\nvar MediaTypes;\n(function (MediaTypes) {\n    MediaTypes[\"ApplicationJson\"] = \"application/json\";\n})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {}));\n/**\n * Returns the proxy URL, depending upon the supplied url and proxy environment variables.\n * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com\n */\nfunction getProxyUrl(serverUrl) {\n    const proxyUrl = pm.getProxyUrl(new URL(serverUrl));\n    return proxyUrl ? proxyUrl.href : '';\n}\nexports.getProxyUrl = getProxyUrl;\nconst HttpRedirectCodes = [\n    HttpCodes.MovedPermanently,\n    HttpCodes.ResourceMoved,\n    HttpCodes.SeeOther,\n    HttpCodes.TemporaryRedirect,\n    HttpCodes.PermanentRedirect\n];\nconst HttpResponseRetryCodes = [\n    HttpCodes.BadGateway,\n    HttpCodes.ServiceUnavailable,\n    HttpCodes.GatewayTimeout\n];\nconst RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];\nconst ExponentialBackoffCeiling = 10;\nconst ExponentialBackoffTimeSlice = 5;\nclass HttpClientError extends Error {\n    constructor(message, statusCode) {\n        super(message);\n        this.name = 'HttpClientError';\n        this.statusCode = statusCode;\n        Object.setPrototypeOf(this, HttpClientError.prototype);\n    }\n}\nexports.HttpClientError = HttpClientError;\nclass HttpClientResponse {\n    constructor(message) {\n        this.message = message;\n    }\n    readBody() {\n        return __awaiter(this, void 0, void 0, function* () {\n            return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {\n                let output = Buffer.alloc(0);\n                this.message.on('data', (chunk) => {\n                    output = Buffer.concat([output, chunk]);\n                });\n                this.message.on('end', () => {\n                    resolve(output.toString());\n                });\n            }));\n        });\n    }\n}\nexports.HttpClientResponse = HttpClientResponse;\nfunction isHttps(requestUrl) {\n    const parsedUrl = new URL(requestUrl);\n    return parsedUrl.protocol === 'https:';\n}\nexports.isHttps = isHttps;\nclass HttpClient {\n    constructor(userAgent, handlers, requestOptions) {\n        this._ignoreSslError = false;\n        this._allowRedirects = true;\n        this._allowRedirectDowngrade = false;\n        this._maxRedirects = 50;\n        this._allowRetries = false;\n        this._maxRetries = 1;\n        this._keepAlive = false;\n        this._disposed = false;\n        this.userAgent = userAgent;\n        this.handlers = handlers || [];\n        this.requestOptions = requestOptions;\n        if (requestOptions) {\n            if (requestOptions.ignoreSslError != null) {\n                this._ignoreSslError = requestOptions.ignoreSslError;\n            }\n            this._socketTimeout = requestOptions.socketTimeout;\n            if (requestOptions.allowRedirects != null) {\n                this._allowRedirects = requestOptions.allowRedirects;\n            }\n            if (requestOptions.allowRedirectDowngrade != null) {\n                this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade;\n            }\n            if (requestOptions.maxRedirects != null) {\n                this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);\n            }\n            if (requestOptions.keepAlive != null) {\n                this._keepAlive = requestOptions.keepAlive;\n            }\n            if (requestOptions.allowRetries != null) {\n                this._allowRetries = requestOptions.allowRetries;\n            }\n            if (requestOptions.maxRetries != null) {\n                this._maxRetries = requestOptions.maxRetries;\n            }\n        }\n    }\n    options(requestUrl, additionalHeaders) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});\n        });\n    }\n    get(requestUrl, additionalHeaders) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.request('GET', requestUrl, null, additionalHeaders || {});\n        });\n    }\n    del(requestUrl, additionalHeaders) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.request('DELETE', requestUrl, null, additionalHeaders || {});\n        });\n    }\n    post(requestUrl, data, additionalHeaders) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.request('POST', requestUrl, data, additionalHeaders || {});\n        });\n    }\n    patch(requestUrl, data, additionalHeaders) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.request('PATCH', requestUrl, data, additionalHeaders || {});\n        });\n    }\n    put(requestUrl, data, additionalHeaders) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.request('PUT', requestUrl, data, additionalHeaders || {});\n        });\n    }\n    head(requestUrl, additionalHeaders) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.request('HEAD', requestUrl, null, additionalHeaders || {});\n        });\n    }\n    sendStream(verb, requestUrl, stream, additionalHeaders) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return this.request(verb, requestUrl, stream, additionalHeaders);\n        });\n    }\n    /**\n     * Gets a typed object from an endpoint\n     * Be aware that not found returns a null.  Other errors (4xx, 5xx) reject the promise\n     */\n    getJson(requestUrl, additionalHeaders = {}) {\n        return __awaiter(this, void 0, void 0, function* () {\n            additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n            const res = yield this.get(requestUrl, additionalHeaders);\n            return this._processResponse(res, this.requestOptions);\n        });\n    }\n    postJson(requestUrl, obj, additionalHeaders = {}) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const data = JSON.stringify(obj, null, 2);\n            additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n            additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n            const res = yield this.post(requestUrl, data, additionalHeaders);\n            return this._processResponse(res, this.requestOptions);\n        });\n    }\n    putJson(requestUrl, obj, additionalHeaders = {}) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const data = JSON.stringify(obj, null, 2);\n            additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n            additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n            const res = yield this.put(requestUrl, data, additionalHeaders);\n            return this._processResponse(res, this.requestOptions);\n        });\n    }\n    patchJson(requestUrl, obj, additionalHeaders = {}) {\n        return __awaiter(this, void 0, void 0, function* () {\n            const data = JSON.stringify(obj, null, 2);\n            additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n            additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n            const res = yield this.patch(requestUrl, data, additionalHeaders);\n            return this._processResponse(res, this.requestOptions);\n        });\n    }\n    /**\n     * Makes a raw http request.\n     * All other methods such as get, post, patch, and request ultimately call this.\n     * Prefer get, del, post and patch\n     */\n    request(verb, requestUrl, data, headers) {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (this._disposed) {\n                throw new Error('Client has already been disposed.');\n            }\n            const parsedUrl = new URL(requestUrl);\n            let info = this._prepareRequest(verb, parsedUrl, headers);\n            // Only perform retries on reads since writes may not be idempotent.\n            const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb)\n                ? this._maxRetries + 1\n                : 1;\n            let numTries = 0;\n            let response;\n            do {\n                response = yield this.requestRaw(info, data);\n                // Check if it's an authentication challenge\n                if (response &&\n                    response.message &&\n                    response.message.statusCode === HttpCodes.Unauthorized) {\n                    let authenticationHandler;\n                    for (const handler of this.handlers) {\n                        if (handler.canHandleAuthentication(response)) {\n                            authenticationHandler = handler;\n                            break;\n                        }\n                    }\n                    if (authenticationHandler) {\n                        return authenticationHandler.handleAuthentication(this, info, data);\n                    }\n                    else {\n                        // We have received an unauthorized response but have no handlers to handle it.\n                        // Let the response return to the caller.\n                        return response;\n                    }\n                }\n                let redirectsRemaining = this._maxRedirects;\n                while (response.message.statusCode &&\n                    HttpRedirectCodes.includes(response.message.statusCode) &&\n                    this._allowRedirects &&\n                    redirectsRemaining > 0) {\n                    const redirectUrl = response.message.headers['location'];\n                    if (!redirectUrl) {\n                        // if there's no location to redirect to, we won't\n                        break;\n                    }\n                    const parsedRedirectUrl = new URL(redirectUrl);\n                    if (parsedUrl.protocol === 'https:' &&\n                        parsedUrl.protocol !== parsedRedirectUrl.protocol &&\n                        !this._allowRedirectDowngrade) {\n                        throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');\n                    }\n                    // we need to finish reading the response before reassigning response\n                    // which will leak the open socket.\n                    yield response.readBody();\n                    // strip authorization header if redirected to a different hostname\n                    if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {\n                        for (const header in headers) {\n                            // header names are case insensitive\n                            if (header.toLowerCase() === 'authorization') {\n                                delete headers[header];\n                            }\n                        }\n                    }\n                    // let's make the request with the new redirectUrl\n                    info = this._prepareRequest(verb, parsedRedirectUrl, headers);\n                    response = yield this.requestRaw(info, data);\n                    redirectsRemaining--;\n                }\n                if (!response.message.statusCode ||\n                    !HttpResponseRetryCodes.includes(response.message.statusCode)) {\n                    // If not a retry code, return immediately instead of retrying\n                    return response;\n                }\n                numTries += 1;\n                if (numTries < maxTries) {\n                    yield response.readBody();\n                    yield this._performExponentialBackoff(numTries);\n                }\n            } while (numTries < maxTries);\n            return response;\n        });\n    }\n    /**\n     * Needs to be called if keepAlive is set to true in request options.\n     */\n    dispose() {\n        if (this._agent) {\n            this._agent.destroy();\n        }\n        this._disposed = true;\n    }\n    /**\n     * Raw request.\n     * @param info\n     * @param data\n     */\n    requestRaw(info, data) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return new Promise((resolve, reject) => {\n                function callbackForResult(err, res) {\n                    if (err) {\n                        reject(err);\n                    }\n                    else if (!res) {\n                        // If `err` is not passed, then `res` must be passed.\n                        reject(new Error('Unknown error'));\n                    }\n                    else {\n                        resolve(res);\n                    }\n                }\n                this.requestRawWithCallback(info, data, callbackForResult);\n            });\n        });\n    }\n    /**\n     * Raw request with callback.\n     * @param info\n     * @param data\n     * @param onResult\n     */\n    requestRawWithCallback(info, data, onResult) {\n        if (typeof data === 'string') {\n            if (!info.options.headers) {\n                info.options.headers = {};\n            }\n            info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');\n        }\n        let callbackCalled = false;\n        function handleResult(err, res) {\n            if (!callbackCalled) {\n                callbackCalled = true;\n                onResult(err, res);\n            }\n        }\n        const req = info.httpModule.request(info.options, (msg) => {\n            const res = new HttpClientResponse(msg);\n            handleResult(undefined, res);\n        });\n        let socket;\n        req.on('socket', sock => {\n            socket = sock;\n        });\n        // If we ever get disconnected, we want the socket to timeout eventually\n        req.setTimeout(this._socketTimeout || 3 * 60000, () => {\n            if (socket) {\n                socket.end();\n            }\n            handleResult(new Error(`Request timeout: ${info.options.path}`));\n        });\n        req.on('error', function (err) {\n            // err has statusCode property\n            // res should have headers\n            handleResult(err);\n        });\n        if (data && typeof data === 'string') {\n            req.write(data, 'utf8');\n        }\n        if (data && typeof data !== 'string') {\n            data.on('close', function () {\n                req.end();\n            });\n            data.pipe(req);\n        }\n        else {\n            req.end();\n        }\n    }\n    /**\n     * Gets an http agent. This function is useful when you need an http agent that handles\n     * routing through a proxy server - depending upon the url and proxy environment variables.\n     * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com\n     */\n    getAgent(serverUrl) {\n        const parsedUrl = new URL(serverUrl);\n        return this._getAgent(parsedUrl);\n    }\n    _prepareRequest(method, requestUrl, headers) {\n        const info = {};\n        info.parsedUrl = requestUrl;\n        const usingSsl = info.parsedUrl.protocol === 'https:';\n        info.httpModule = usingSsl ? https : http;\n        const defaultPort = usingSsl ? 443 : 80;\n        info.options = {};\n        info.options.host = info.parsedUrl.hostname;\n        info.options.port = info.parsedUrl.port\n            ? parseInt(info.parsedUrl.port)\n            : defaultPort;\n        info.options.path =\n            (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');\n        info.options.method = method;\n        info.options.headers = this._mergeHeaders(headers);\n        if (this.userAgent != null) {\n            info.options.headers['user-agent'] = this.userAgent;\n        }\n        info.options.agent = this._getAgent(info.parsedUrl);\n        // gives handlers an opportunity to participate\n        if (this.handlers) {\n            for (const handler of this.handlers) {\n                handler.prepareRequest(info.options);\n            }\n        }\n        return info;\n    }\n    _mergeHeaders(headers) {\n        if (this.requestOptions && this.requestOptions.headers) {\n            return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {}));\n        }\n        return lowercaseKeys(headers || {});\n    }\n    _getExistingOrDefaultHeader(additionalHeaders, header, _default) {\n        let clientHeader;\n        if (this.requestOptions && this.requestOptions.headers) {\n            clientHeader = lowercaseKeys(this.requestOptions.headers)[header];\n        }\n        return additionalHeaders[header] || clientHeader || _default;\n    }\n    _getAgent(parsedUrl) {\n        let agent;\n        const proxyUrl = pm.getProxyUrl(parsedUrl);\n        const useProxy = proxyUrl && proxyUrl.hostname;\n        if (this._keepAlive && useProxy) {\n            agent = this._proxyAgent;\n        }\n        if (this._keepAlive && !useProxy) {\n            agent = this._agent;\n        }\n        // if agent is already assigned use that agent.\n        if (agent) {\n            return agent;\n        }\n        const usingSsl = parsedUrl.protocol === 'https:';\n        let maxSockets = 100;\n        if (this.requestOptions) {\n            maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;\n        }\n        // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis.\n        if (proxyUrl && proxyUrl.hostname) {\n            const agentOptions = {\n                maxSockets,\n                keepAlive: this._keepAlive,\n                proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && {\n                    proxyAuth: `${proxyUrl.username}:${proxyUrl.password}`\n                })), { host: proxyUrl.hostname, port: proxyUrl.port })\n            };\n            let tunnelAgent;\n            const overHttps = proxyUrl.protocol === 'https:';\n            if (usingSsl) {\n                tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;\n            }\n            else {\n                tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;\n            }\n            agent = tunnelAgent(agentOptions);\n            this._proxyAgent = agent;\n        }\n        // if reusing agent across request and tunneling agent isn't assigned create a new agent\n        if (this._keepAlive && !agent) {\n            const options = { keepAlive: this._keepAlive, maxSockets };\n            agent = usingSsl ? new https.Agent(options) : new http.Agent(options);\n            this._agent = agent;\n        }\n        // if not using private agent and tunnel agent isn't setup then use global agent\n        if (!agent) {\n            agent = usingSsl ? https.globalAgent : http.globalAgent;\n        }\n        if (usingSsl && this._ignoreSslError) {\n            // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process\n            // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options\n            // we have to cast it to any and change it directly\n            agent.options = Object.assign(agent.options || {}, {\n                rejectUnauthorized: false\n            });\n        }\n        return agent;\n    }\n    _performExponentialBackoff(retryNumber) {\n        return __awaiter(this, void 0, void 0, function* () {\n            retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);\n            const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);\n            return new Promise(resolve => setTimeout(() => resolve(), ms));\n        });\n    }\n    _processResponse(res, options) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n                const statusCode = res.message.statusCode || 0;\n                const response = {\n                    statusCode,\n                    result: null,\n                    headers: {}\n                };\n                // not found leads to null obj returned\n                if (statusCode === HttpCodes.NotFound) {\n                    resolve(response);\n                }\n                // get the result from the body\n                function dateTimeDeserializer(key, value) {\n                    if (typeof value === 'string') {\n                        const a = new Date(value);\n                        if (!isNaN(a.valueOf())) {\n                            return a;\n                        }\n                    }\n                    return value;\n                }\n                let obj;\n                let contents;\n                try {\n                    contents = yield res.readBody();\n                    if (contents && contents.length > 0) {\n                        if (options && options.deserializeDates) {\n                            obj = JSON.parse(contents, dateTimeDeserializer);\n                        }\n                        else {\n                            obj = JSON.parse(contents);\n                        }\n                        response.result = obj;\n                    }\n                    response.headers = res.message.headers;\n                }\n                catch (err) {\n                    // Invalid resource (contents not json);  leaving result obj null\n                }\n                // note that 3xx redirects are handled by the http layer.\n                if (statusCode > 299) {\n                    let msg;\n                    // if exception/error in body, attempt to get better error\n                    if (obj && obj.message) {\n                        msg = obj.message;\n                    }\n                    else if (contents && contents.length > 0) {\n                        // it may be the case that the exception is in the body message as string\n                        msg = contents;\n                    }\n                    else {\n                        msg = `Failed request: (${statusCode})`;\n                    }\n                    const err = new HttpClientError(msg, statusCode);\n                    err.result = response.result;\n                    reject(err);\n                }\n                else {\n                    resolve(response);\n                }\n            }));\n        });\n    }\n}\nexports.HttpClient = HttpClient;\nconst lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});\n//# sourceMappingURL=index.js.map\n\n/***/ }),\n\n/***/ 9835:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.checkBypass = exports.getProxyUrl = void 0;\nfunction getProxyUrl(reqUrl) {\n    const usingSsl = reqUrl.protocol === 'https:';\n    if (checkBypass(reqUrl)) {\n        return undefined;\n    }\n    const proxyVar = (() => {\n        if (usingSsl) {\n            return process.env['https_proxy'] || process.env['HTTPS_PROXY'];\n        }\n        else {\n            return process.env['http_proxy'] || process.env['HTTP_PROXY'];\n        }\n    })();\n    if (proxyVar) {\n        return new URL(proxyVar);\n    }\n    else {\n        return undefined;\n    }\n}\nexports.getProxyUrl = getProxyUrl;\nfunction checkBypass(reqUrl) {\n    if (!reqUrl.hostname) {\n        return false;\n    }\n    const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';\n    if (!noProxy) {\n        return false;\n    }\n    // Determine the request port\n    let reqPort;\n    if (reqUrl.port) {\n        reqPort = Number(reqUrl.port);\n    }\n    else if (reqUrl.protocol === 'http:') {\n        reqPort = 80;\n    }\n    else if (reqUrl.protocol === 'https:') {\n        reqPort = 443;\n    }\n    // Format the request hostname and hostname with port\n    const upperReqHosts = [reqUrl.hostname.toUpperCase()];\n    if (typeof reqPort === 'number') {\n        upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);\n    }\n    // Compare request host against noproxy\n    for (const upperNoProxyItem of noProxy\n        .split(',')\n        .map(x => x.trim().toUpperCase())\n        .filter(x => x)) {\n        if (upperReqHosts.some(x => x === upperNoProxyItem)) {\n            return true;\n        }\n    }\n    return false;\n}\nexports.checkBypass = checkBypass;\n//# sourceMappingURL=proxy.js.map\n\n/***/ }),\n\n/***/ 9417:\n/***/ ((module) => {\n\n\"use strict\";\n\nmodule.exports = balanced;\nfunction balanced(a, b, str) {\n  if (a instanceof RegExp) a = maybeMatch(a, str);\n  if (b instanceof RegExp) b = maybeMatch(b, str);\n\n  var r = range(a, b, str);\n\n  return r && {\n    start: r[0],\n    end: r[1],\n    pre: str.slice(0, r[0]),\n    body: str.slice(r[0] + a.length, r[1]),\n    post: str.slice(r[1] + b.length)\n  };\n}\n\nfunction maybeMatch(reg, str) {\n  var m = str.match(reg);\n  return m ? m[0] : null;\n}\n\nbalanced.range = range;\nfunction range(a, b, str) {\n  var begs, beg, left, right, result;\n  var ai = str.indexOf(a);\n  var bi = str.indexOf(b, ai + 1);\n  var i = ai;\n\n  if (ai >= 0 && bi > 0) {\n    begs = [];\n    left = str.length;\n\n    while (i >= 0 && !result) {\n      if (i == ai) {\n        begs.push(i);\n        ai = str.indexOf(a, i + 1);\n      } else if (begs.length == 1) {\n        result = [ begs.pop(), bi ];\n      } else {\n        beg = begs.pop();\n        if (beg < left) {\n          left = beg;\n          right = bi;\n        }\n\n        bi = str.indexOf(b, i + 1);\n      }\n\n      i = ai < bi && ai >= 0 ? ai : bi;\n    }\n\n    if (begs.length) {\n      result = [ left, right ];\n    }\n  }\n\n  return result;\n}\n\n\n/***/ }),\n\n/***/ 3717:\n/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {\n\nvar concatMap = __nccwpck_require__(6891);\nvar balanced = __nccwpck_require__(9417);\n\nmodule.exports = expandTop;\n\nvar escSlash = '\\0SLASH'+Math.random()+'\\0';\nvar escOpen = '\\0OPEN'+Math.random()+'\\0';\nvar escClose = '\\0CLOSE'+Math.random()+'\\0';\nvar escComma = '\\0COMMA'+Math.random()+'\\0';\nvar escPeriod = '\\0PERIOD'+Math.random()+'\\0';\n\nfunction numeric(str) {\n  return parseInt(str, 10) == str\n    ? parseInt(str, 10)\n    : str.charCodeAt(0);\n}\n\nfunction escapeBraces(str) {\n  return str.split('\\\\\\\\').join(escSlash)\n            .split('\\\\{').join(escOpen)\n            .split('\\\\}').join(escClose)\n            .split('\\\\,').join(escComma)\n            .split('\\\\.').join(escPeriod);\n}\n\nfunction unescapeBraces(str) {\n  return str.split(escSlash).join('\\\\')\n            .split(escOpen).join('{')\n            .split(escClose).join('}')\n            .split(escComma).join(',')\n            .split(escPeriod).join('.');\n}\n\n\n// Basically just str.split(\",\"), but handling cases\n// where we have nested braced sections, which should be\n// treated as individual members, like {a,{b,c},d}\nfunction parseCommaParts(str) {\n  if (!str)\n    return [''];\n\n  var parts = [];\n  var m = balanced('{', '}', str);\n\n  if (!m)\n    return str.split(',');\n\n  var pre = m.pre;\n  var body = m.body;\n  var post = m.post;\n  var p = pre.split(',');\n\n  p[p.length-1] += '{' + body + '}';\n  var postParts = parseCommaParts(post);\n  if (post.length) {\n    p[p.length-1] += postParts.shift();\n    p.push.apply(p, postParts);\n  }\n\n  parts.push.apply(parts, p);\n\n  return parts;\n}\n\nfunction expandTop(str) {\n  if (!str)\n    return [];\n\n  // I don't know why Bash 4.3 does this, but it does.\n  // Anything starting with {} will have the first two bytes preserved\n  // but *only* at the top level, so {},a}b will not expand to anything,\n  // but a{},b}c will be expanded to [a}c,abc].\n  // One could argue that this is a bug in Bash, but since the goal of\n  // this module is to match Bash's rules, we escape a leading {}\n  if (str.substr(0, 2) === '{}') {\n    str = '\\\\{\\\\}' + str.substr(2);\n  }\n\n  return expand(escapeBraces(str), true).map(unescapeBraces);\n}\n\nfunction identity(e) {\n  return e;\n}\n\nfunction embrace(str) {\n  return '{' + str + '}';\n}\nfunction isPadded(el) {\n  return /^-?0\\d/.test(el);\n}\n\nfunction lte(i, y) {\n  return i <= y;\n}\nfunction gte(i, y) {\n  return i >= y;\n}\n\nfunction expand(str, isTop) {\n  var expansions = [];\n\n  var m = balanced('{', '}', str);\n  if (!m || /\\$$/.test(m.pre)) return [str];\n\n  var isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body);\n  var isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(m.body);\n  var isSequence = isNumericSequence || isAlphaSequence;\n  var isOptions = m.body.indexOf(',') >= 0;\n  if (!isSequence && !isOptions) {\n    // {a},b}\n    if (m.post.match(/,.*\\}/)) {\n      str = m.pre + '{' + m.body + escClose + m.post;\n      return expand(str);\n    }\n    return [str];\n  }\n\n  var n;\n  if (isSequence) {\n    n = m.body.split(/\\.\\./);\n  } else {\n    n = parseCommaParts(m.body);\n    if (n.length === 1) {\n      // x{{a,b}}y ==> x{a}y x{b}y\n      n = expand(n[0], false).map(embrace);\n      if (n.length === 1) {\n        var post = m.post.length\n          ? expand(m.post, false)\n          : [''];\n        return post.map(function(p) {\n          return m.pre + n[0] + p;\n        });\n      }\n    }\n  }\n\n  // at this point, n is the parts, and we know it's not a comma set\n  // with a single entry.\n\n  // no need to expand pre, since it is guaranteed to be free of brace-sets\n  var pre = m.pre;\n  var post = m.post.length\n    ? expand(m.post, false)\n    : [''];\n\n  var N;\n\n  if (isSequence) {\n    var x = numeric(n[0]);\n    var y = numeric(n[1]);\n    var width = Math.max(n[0].length, n[1].length)\n    var incr = n.length == 3\n      ? Math.abs(numeric(n[2]))\n      : 1;\n    var test = lte;\n    var reverse = y < x;\n    if (reverse) {\n      incr *= -1;\n      test = gte;\n    }\n    var pad = n.some(isPadded);\n\n    N = [];\n\n    for (var i = x; test(i, y); i += incr) {\n      var c;\n      if (isAlphaSequence) {\n        c = String.fromCharCode(i);\n        if (c === '\\\\')\n          c = '';\n      } else {\n        c = String(i);\n        if (pad) {\n          var need = width - c.length;\n          if (need > 0) {\n            var z = new Array(need + 1).join('0');\n            if (i < 0)\n              c = '-' + z + c.slice(1);\n            else\n              c = z + c;\n          }\n        }\n      }\n      N.push(c);\n    }\n  } else {\n    N = concatMap(n, function(el) { return expand(el, false) });\n  }\n\n  for (var j = 0; j < N.length; j++) {\n    for (var k = 0; k < post.length; k++) {\n      var expansion = pre + N[j] + post[k];\n      if (!isTop || isSequence || expansion)\n        expansions.push(expansion);\n    }\n  }\n\n  return expansions;\n}\n\n\n\n/***/ }),\n\n/***/ 6891:\n/***/ ((module) => {\n\nmodule.exports = function (xs, fn) {\n    var res = [];\n    for (var i = 0; i < xs.length; i++) {\n        var x = fn(xs[i], i);\n        if (isArray(x)) res.push.apply(res, x);\n        else res.push(x);\n    }\n    return res;\n};\n\nvar isArray = Array.isArray || function (xs) {\n    return Object.prototype.toString.call(xs) === '[object Array]';\n};\n\n\n/***/ }),\n\n/***/ 3973:\n/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {\n\nmodule.exports = minimatch\nminimatch.Minimatch = Minimatch\n\nvar path = (function () { try { return __nccwpck_require__(1017) } catch (e) {}}()) || {\n  sep: '/'\n}\nminimatch.sep = path.sep\n\nvar GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}\nvar expand = __nccwpck_require__(3717)\n\nvar plTypes = {\n  '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},\n  '?': { open: '(?:', close: ')?' },\n  '+': { open: '(?:', close: ')+' },\n  '*': { open: '(?:', close: ')*' },\n  '@': { open: '(?:', close: ')' }\n}\n\n// any single thing other than /\n// don't need to escape / when using new RegExp()\nvar qmark = '[^/]'\n\n// * => any number of characters\nvar star = qmark + '*?'\n\n// ** when dots are allowed.  Anything goes, except .. and .\n// not (^ or / followed by one or two dots followed by $ or /),\n// followed by anything, any number of times.\nvar twoStarDot = '(?:(?!(?:\\\\\\/|^)(?:\\\\.{1,2})($|\\\\\\/)).)*?'\n\n// not a ^ or / followed by a dot,\n// followed by anything, any number of times.\nvar twoStarNoDot = '(?:(?!(?:\\\\\\/|^)\\\\.).)*?'\n\n// characters that need to be escaped in RegExp.\nvar reSpecials = charSet('().*{}+?[]^$\\\\!')\n\n// \"abc\" -> { a:true, b:true, c:true }\nfunction charSet (s) {\n  return s.split('').reduce(function (set, c) {\n    set[c] = true\n    return set\n  }, {})\n}\n\n// normalizes slashes.\nvar slashSplit = /\\/+/\n\nminimatch.filter = filter\nfunction filter (pattern, options) {\n  options = options || {}\n  return function (p, i, list) {\n    return minimatch(p, pattern, options)\n  }\n}\n\nfunction ext (a, b) {\n  b = b || {}\n  var t = {}\n  Object.keys(a).forEach(function (k) {\n    t[k] = a[k]\n  })\n  Object.keys(b).forEach(function (k) {\n    t[k] = b[k]\n  })\n  return t\n}\n\nminimatch.defaults = function (def) {\n  if (!def || typeof def !== 'object' || !Object.keys(def).length) {\n    return minimatch\n  }\n\n  var orig = minimatch\n\n  var m = function minimatch (p, pattern, options) {\n    return orig(p, pattern, ext(def, options))\n  }\n\n  m.Minimatch = function Minimatch (pattern, options) {\n    return new orig.Minimatch(pattern, ext(def, options))\n  }\n  m.Minimatch.defaults = function defaults (options) {\n    return orig.defaults(ext(def, options)).Minimatch\n  }\n\n  m.filter = function filter (pattern, options) {\n    return orig.filter(pattern, ext(def, options))\n  }\n\n  m.defaults = function defaults (options) {\n    return orig.defaults(ext(def, options))\n  }\n\n  m.makeRe = function makeRe (pattern, options) {\n    return orig.makeRe(pattern, ext(def, options))\n  }\n\n  m.braceExpand = function braceExpand (pattern, options) {\n    return orig.braceExpand(pattern, ext(def, options))\n  }\n\n  m.match = function (list, pattern, options) {\n    return orig.match(list, pattern, ext(def, options))\n  }\n\n  return m\n}\n\nMinimatch.defaults = function (def) {\n  return minimatch.defaults(def).Minimatch\n}\n\nfunction minimatch (p, pattern, options) {\n  assertValidPattern(pattern)\n\n  if (!options) options = {}\n\n  // shortcut: comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    return false\n  }\n\n  return new Minimatch(pattern, options).match(p)\n}\n\nfunction Minimatch (pattern, options) {\n  if (!(this instanceof Minimatch)) {\n    return new Minimatch(pattern, options)\n  }\n\n  assertValidPattern(pattern)\n\n  if (!options) options = {}\n\n  pattern = pattern.trim()\n\n  // windows support: need to use /, not \\\n  if (!options.allowWindowsEscape && path.sep !== '/') {\n    pattern = pattern.split(path.sep).join('/')\n  }\n\n  this.options = options\n  this.set = []\n  this.pattern = pattern\n  this.regexp = null\n  this.negate = false\n  this.comment = false\n  this.empty = false\n  this.partial = !!options.partial\n\n  // make the set of regexps etc.\n  this.make()\n}\n\nMinimatch.prototype.debug = function () {}\n\nMinimatch.prototype.make = make\nfunction make () {\n  var pattern = this.pattern\n  var options = this.options\n\n  // empty patterns and comments match nothing.\n  if (!options.nocomment && pattern.charAt(0) === '#') {\n    this.comment = true\n    return\n  }\n  if (!pattern) {\n    this.empty = true\n    return\n  }\n\n  // step 1: figure out negation, etc.\n  this.parseNegate()\n\n  // step 2: expand braces\n  var set = this.globSet = this.braceExpand()\n\n  if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) }\n\n  this.debug(this.pattern, set)\n\n  // step 3: now we have a set, so turn each one into a series of path-portion\n  // matching patterns.\n  // These will be regexps, except in the case of \"**\", which is\n  // set to the GLOBSTAR object for globstar behavior,\n  // and will not contain any / characters\n  set = this.globParts = set.map(function (s) {\n    return s.split(slashSplit)\n  })\n\n  this.debug(this.pattern, set)\n\n  // glob --> regexps\n  set = set.map(function (s, si, set) {\n    return s.map(this.parse, this)\n  }, this)\n\n  this.debug(this.pattern, set)\n\n  // filter out everything that didn't compile properly.\n  set = set.filter(function (s) {\n    return s.indexOf(false) === -1\n  })\n\n  this.debug(this.pattern, set)\n\n  this.set = set\n}\n\nMinimatch.prototype.parseNegate = parseNegate\nfunction parseNegate () {\n  var pattern = this.pattern\n  var negate = false\n  var options = this.options\n  var negateOffset = 0\n\n  if (options.nonegate) return\n\n  for (var i = 0, l = pattern.length\n    ; i < l && pattern.charAt(i) === '!'\n    ; i++) {\n    negate = !negate\n    negateOffset++\n  }\n\n  if (negateOffset) this.pattern = pattern.substr(negateOffset)\n  this.negate = negate\n}\n\n// Brace expansion:\n// a{b,c}d -> abd acd\n// a{b,}c -> abc ac\n// a{0..3}d -> a0d a1d a2d a3d\n// a{b,c{d,e}f}g -> abg acdfg acefg\n// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg\n//\n// Invalid sets are not expanded.\n// a{2..}b -> a{2..}b\n// a{b}c -> a{b}c\nminimatch.braceExpand = function (pattern, options) {\n  return braceExpand(pattern, options)\n}\n\nMinimatch.prototype.braceExpand = braceExpand\n\nfunction braceExpand (pattern, options) {\n  if (!options) {\n    if (this instanceof Minimatch) {\n      options = this.options\n    } else {\n      options = {}\n    }\n  }\n\n  pattern = typeof pattern === 'undefined'\n    ? this.pattern : pattern\n\n  assertValidPattern(pattern)\n\n  // Thanks to Yeting Li <https://github.com/yetingli> for\n  // improving this regexp to avoid a ReDOS vulnerability.\n  if (options.nobrace || !/\\{(?:(?!\\{).)*\\}/.test(pattern)) {\n    // shortcut. no need to expand.\n    return [pattern]\n  }\n\n  return expand(pattern)\n}\n\nvar MAX_PATTERN_LENGTH = 1024 * 64\nvar assertValidPattern = function (pattern) {\n  if (typeof pattern !== 'string') {\n    throw new TypeError('invalid pattern')\n  }\n\n  if (pattern.length > MAX_PATTERN_LENGTH) {\n    throw new TypeError('pattern is too long')\n  }\n}\n\n// parse a component of the expanded set.\n// At this point, no pattern may contain \"/\" in it\n// so we're going to return a 2d array, where each entry is the full\n// pattern, split on '/', and then turned into a regular expression.\n// A regexp is made at the end which joins each array with an\n// escaped /, and another full one which joins each regexp with |.\n//\n// Following the lead of Bash 4.1, note that \"**\" only has special meaning\n// when it is the *only* thing in a path portion.  Otherwise, any series\n// of * is equivalent to a single *.  Globstar behavior is enabled by\n// default, and can be disabled by setting options.noglobstar.\nMinimatch.prototype.parse = parse\nvar SUBPARSE = {}\nfunction parse (pattern, isSub) {\n  assertValidPattern(pattern)\n\n  var options = this.options\n\n  // shortcuts\n  if (pattern === '**') {\n    if (!options.noglobstar)\n      return GLOBSTAR\n    else\n      pattern = '*'\n  }\n  if (pattern === '') return ''\n\n  var re = ''\n  var hasMagic = !!options.nocase\n  var escaping = false\n  // ? => one single character\n  var patternListStack = []\n  var negativeLists = []\n  var stateChar\n  var inClass = false\n  var reClassStart = -1\n  var classStart = -1\n  // . and .. never match anything that doesn't start with .,\n  // even when options.dot is set.\n  var patternStart = pattern.charAt(0) === '.' ? '' // anything\n  // not (start or / followed by . or .. followed by / or end)\n  : options.dot ? '(?!(?:^|\\\\\\/)\\\\.{1,2}(?:$|\\\\\\/))'\n  : '(?!\\\\.)'\n  var self = this\n\n  function clearStateChar () {\n    if (stateChar) {\n      // we had some state-tracking character\n      // that wasn't consumed by this pass.\n      switch (stateChar) {\n        case '*':\n          re += star\n          hasMagic = true\n        break\n        case '?':\n          re += qmark\n          hasMagic = true\n        break\n        default:\n          re += '\\\\' + stateChar\n        break\n      }\n      self.debug('clearStateChar %j %j', stateChar, re)\n      stateChar = false\n    }\n  }\n\n  for (var i = 0, len = pattern.length, c\n    ; (i < len) && (c = pattern.charAt(i))\n    ; i++) {\n    this.debug('%s\\t%s %s %j', pattern, i, re, c)\n\n    // skip over any that are escaped.\n    if (escaping && reSpecials[c]) {\n      re += '\\\\' + c\n      escaping = false\n      continue\n    }\n\n    switch (c) {\n      /* istanbul ignore next */\n      case '/': {\n        // completely not allowed, even escaped.\n        // Should already be path-split by now.\n        return false\n      }\n\n      case '\\\\':\n        clearStateChar()\n        escaping = true\n      continue\n\n      // the various stateChar values\n      // for the \"extglob\" stuff.\n      case '?':\n      case '*':\n      case '+':\n      case '@':\n      case '!':\n        this.debug('%s\\t%s %s %j <-- stateChar', pattern, i, re, c)\n\n        // all of those are literals inside a class, except that\n        // the glob [!a] means [^a] in regexp\n        if (inClass) {\n          this.debug('  in class')\n          if (c === '!' && i === classStart + 1) c = '^'\n          re += c\n          continue\n        }\n\n        // if we already have a stateChar, then it means\n        // that there was something like ** or +? in there.\n        // Handle the stateChar, then proceed with this one.\n        self.debug('call clearStateChar %j', stateChar)\n        clearStateChar()\n        stateChar = c\n        // if extglob is disabled, then +(asdf|foo) isn't a thing.\n        // just clear the statechar *now*, rather than even diving into\n        // the patternList stuff.\n        if (options.noext) clearStateChar()\n      continue\n\n      case '(':\n        if (inClass) {\n          re += '('\n          continue\n        }\n\n        if (!stateChar) {\n          re += '\\\\('\n          continue\n        }\n\n        patternListStack.push({\n          type: stateChar,\n          start: i - 1,\n          reStart: re.length,\n          open: plTypes[stateChar].open,\n          close: plTypes[stateChar].close\n        })\n        // negation is (?:(?!js)[^/]*)\n        re += stateChar === '!' ? '(?:(?!(?:' : '(?:'\n        this.debug('plType %j %j', stateChar, re)\n        stateChar = false\n      continue\n\n      case ')':\n        if (inClass || !patternListStack.length) {\n          re += '\\\\)'\n          continue\n        }\n\n        clearStateChar()\n        hasMagic = true\n        var pl = patternListStack.pop()\n        // negation is (?:(?!js)[^/]*)\n        // The others are (?:<pattern>)<type>\n        re += pl.close\n        if (pl.type === '!') {\n          negativeLists.push(pl)\n        }\n        pl.reEnd = re.length\n      continue\n\n      case '|':\n        if (inClass || !patternListStack.length || escaping) {\n          re += '\\\\|'\n          escaping = false\n          continue\n        }\n\n        clearStateChar()\n        re += '|'\n      continue\n\n      // these are mostly the same in regexp and glob\n      case '[':\n        // swallow any state-tracking char before the [\n        clearStateChar()\n\n        if (inClass) {\n          re += '\\\\' + c\n          continue\n        }\n\n        inClass = true\n        classStart = i\n        reClassStart = re.length\n        re += c\n      continue\n\n      case ']':\n        //  a right bracket shall lose its special\n        //  meaning and represent itself in\n        //  a bracket expression if it occurs\n        //  first in the list.  -- POSIX.2 2.8.3.2\n        if (i === classStart + 1 || !inClass) {\n          re += '\\\\' + c\n          escaping = false\n          continue\n        }\n\n        // handle the case where we left a class open.\n        // \"[z-a]\" is valid, equivalent to \"\\[z-a\\]\"\n        // split where the last [ was, make sure we don't have\n        // an invalid re. if so, re-walk the contents of the\n        // would-be class to re-translate any characters that\n        // were passed through as-is\n        // TODO: It would probably be faster to determine this\n        // without a try/catch and a new RegExp, but it's tricky\n        // to do safely.  For now, this is safe and works.\n        var cs = pattern.substring(classStart + 1, i)\n        try {\n          RegExp('[' + cs + ']')\n        } catch (er) {\n          // not a valid class!\n          var sp = this.parse(cs, SUBPARSE)\n          re = re.substr(0, reClassStart) + '\\\\[' + sp[0] + '\\\\]'\n          hasMagic = hasMagic || sp[1]\n          inClass = false\n          continue\n        }\n\n        // finish up the class.\n        hasMagic = true\n        inClass = false\n        re += c\n      continue\n\n      default:\n        // swallow any state char that wasn't consumed\n        clearStateChar()\n\n        if (escaping) {\n          // no need\n          escaping = false\n        } else if (reSpecials[c]\n          && !(c === '^' && inClass)) {\n          re += '\\\\'\n        }\n\n        re += c\n\n    } // switch\n  } // for\n\n  // handle the case where we left a class open.\n  // \"[abc\" is valid, equivalent to \"\\[abc\"\n  if (inClass) {\n    // split where the last [ was, and escape it\n    // this is a huge pita.  We now have to re-walk\n    // the contents of the would-be class to re-translate\n    // any characters that were passed through as-is\n    cs = pattern.substr(classStart + 1)\n    sp = this.parse(cs, SUBPARSE)\n    re = re.substr(0, reClassStart) + '\\\\[' + sp[0]\n    hasMagic = hasMagic || sp[1]\n  }\n\n  // handle the case where we had a +( thing at the *end*\n  // of the pattern.\n  // each pattern list stack adds 3 chars, and we need to go through\n  // and escape any | chars that were passed through as-is for the regexp.\n  // Go through and escape them, taking care not to double-escape any\n  // | chars that were already escaped.\n  for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {\n    var tail = re.slice(pl.reStart + pl.open.length)\n    this.debug('setting tail', re, pl)\n    // maybe some even number of \\, then maybe 1 \\, followed by a |\n    tail = tail.replace(/((?:\\\\{2}){0,64})(\\\\?)\\|/g, function (_, $1, $2) {\n      if (!$2) {\n        // the | isn't already escaped, so escape it.\n        $2 = '\\\\'\n      }\n\n      // need to escape all those slashes *again*, without escaping the\n      // one that we need for escaping the | character.  As it works out,\n      // escaping an even number of slashes can be done by simply repeating\n      // it exactly after itself.  That's why this trick works.\n      //\n      // I am sorry that you have to see this.\n      return $1 + $1 + $2 + '|'\n    })\n\n    this.debug('tail=%j\\n   %s', tail, tail, pl, re)\n    var t = pl.type === '*' ? star\n      : pl.type === '?' ? qmark\n      : '\\\\' + pl.type\n\n    hasMagic = true\n    re = re.slice(0, pl.reStart) + t + '\\\\(' + tail\n  }\n\n  // handle trailing things that only matter at the very end.\n  clearStateChar()\n  if (escaping) {\n    // trailing \\\\\n    re += '\\\\\\\\'\n  }\n\n  // only need to apply the nodot start if the re starts with\n  // something that could conceivably capture a dot\n  var addPatternStart = false\n  switch (re.charAt(0)) {\n    case '[': case '.': case '(': addPatternStart = true\n  }\n\n  // Hack to work around lack of negative lookbehind in JS\n  // A pattern like: *.!(x).!(y|z) needs to ensure that a name\n  // like 'a.xyz.yz' doesn't match.  So, the first negative\n  // lookahead, has to look ALL the way ahead, to the end of\n  // the pattern.\n  for (var n = negativeLists.length - 1; n > -1; n--) {\n    var nl = negativeLists[n]\n\n    var nlBefore = re.slice(0, nl.reStart)\n    var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)\n    var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)\n    var nlAfter = re.slice(nl.reEnd)\n\n    nlLast += nlAfter\n\n    // Handle nested stuff like *(*.js|!(*.json)), where open parens\n    // mean that we should *not* include the ) in the bit that is considered\n    // \"after\" the negated section.\n    var openParensBefore = nlBefore.split('(').length - 1\n    var cleanAfter = nlAfter\n    for (i = 0; i < openParensBefore; i++) {\n      cleanAfter = cleanAfter.replace(/\\)[+*?]?/, '')\n    }\n    nlAfter = cleanAfter\n\n    var dollar = ''\n    if (nlAfter === '' && isSub !== SUBPARSE) {\n      dollar = '$'\n    }\n    var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast\n    re = newRe\n  }\n\n  // if the re is not \"\" at this point, then we need to make sure\n  // it doesn't match against an empty path part.\n  // Otherwise a/* will match a/, which it should not.\n  if (re !== '' && hasMagic) {\n    re = '(?=.)' + re\n  }\n\n  if (addPatternStart) {\n    re = patternStart + re\n  }\n\n  // parsing just a piece of a larger pattern.\n  if (isSub === SUBPARSE) {\n    return [re, hasMagic]\n  }\n\n  // skip the regexp for non-magical patterns\n  // unescape anything in it, though, so that it'll be\n  // an exact match against a file etc.\n  if (!hasMagic) {\n    return globUnescape(pattern)\n  }\n\n  var flags = options.nocase ? 'i' : ''\n  try {\n    var regExp = new RegExp('^' + re + '$', flags)\n  } catch (er) /* istanbul ignore next - should be impossible */ {\n    // If it was an invalid regular expression, then it can't match\n    // anything.  This trick looks for a character after the end of\n    // the string, which is of course impossible, except in multi-line\n    // mode, but it's not a /m regex.\n    return new RegExp('$.')\n  }\n\n  regExp._glob = pattern\n  regExp._src = re\n\n  return regExp\n}\n\nminimatch.makeRe = function (pattern, options) {\n  return new Minimatch(pattern, options || {}).makeRe()\n}\n\nMinimatch.prototype.makeRe = makeRe\nfunction makeRe () {\n  if (this.regexp || this.regexp === false) return this.regexp\n\n  // at this point, this.set is a 2d array of partial\n  // pattern strings, or \"**\".\n  //\n  // It's better to use .match().  This function shouldn't\n  // be used, really, but it's pretty convenient sometimes,\n  // when you just want to work with a regex.\n  var set = this.set\n\n  if (!set.length) {\n    this.regexp = false\n    return this.regexp\n  }\n  var options = this.options\n\n  var twoStar = options.noglobstar ? star\n    : options.dot ? twoStarDot\n    : twoStarNoDot\n  var flags = options.nocase ? 'i' : ''\n\n  var re = set.map(function (pattern) {\n    return pattern.map(function (p) {\n      return (p === GLOBSTAR) ? twoStar\n      : (typeof p === 'string') ? regExpEscape(p)\n      : p._src\n    }).join('\\\\\\/')\n  }).join('|')\n\n  // must match entire pattern\n  // ending in a * or ** will make it less strict.\n  re = '^(?:' + re + ')$'\n\n  // can match anything, as long as it's not this.\n  if (this.negate) re = '^(?!' + re + ').*$'\n\n  try {\n    this.regexp = new RegExp(re, flags)\n  } catch (ex) /* istanbul ignore next - should be impossible */ {\n    this.regexp = false\n  }\n  return this.regexp\n}\n\nminimatch.match = function (list, pattern, options) {\n  options = options || {}\n  var mm = new Minimatch(pattern, options)\n  list = list.filter(function (f) {\n    return mm.match(f)\n  })\n  if (mm.options.nonull && !list.length) {\n    list.push(pattern)\n  }\n  return list\n}\n\nMinimatch.prototype.match = function match (f, partial) {\n  if (typeof partial === 'undefined') partial = this.partial\n  this.debug('match', f, this.pattern)\n  // short-circuit in the case of busted things.\n  // comments, etc.\n  if (this.comment) return false\n  if (this.empty) return f === ''\n\n  if (f === '/' && partial) return true\n\n  var options = this.options\n\n  // windows: need to use /, not \\\n  if (path.sep !== '/') {\n    f = f.split(path.sep).join('/')\n  }\n\n  // treat the test path as a set of pathparts.\n  f = f.split(slashSplit)\n  this.debug(this.pattern, 'split', f)\n\n  // just ONE of the pattern sets in this.set needs to match\n  // in order for it to be valid.  If negating, then just one\n  // match means that we have failed.\n  // Either way, return on the first hit.\n\n  var set = this.set\n  this.debug(this.pattern, 'set', set)\n\n  // Find the basename of the path by looking for the last non-empty segment\n  var filename\n  var i\n  for (i = f.length - 1; i >= 0; i--) {\n    filename = f[i]\n    if (filename) break\n  }\n\n  for (i = 0; i < set.length; i++) {\n    var pattern = set[i]\n    var file = f\n    if (options.matchBase && pattern.length === 1) {\n      file = [filename]\n    }\n    var hit = this.matchOne(file, pattern, partial)\n    if (hit) {\n      if (options.flipNegate) return true\n      return !this.negate\n    }\n  }\n\n  // didn't get any hits.  this is success if it's a negative\n  // pattern, failure otherwise.\n  if (options.flipNegate) return false\n  return this.negate\n}\n\n// set partial to true to test if, for example,\n// \"/a/b\" matches the start of \"/*/b/*/d\"\n// Partial means, if you run out of file before you run\n// out of pattern, then that's fine, as long as all\n// the parts match.\nMinimatch.prototype.matchOne = function (file, pattern, partial) {\n  var options = this.options\n\n  this.debug('matchOne',\n    { 'this': this, file: file, pattern: pattern })\n\n  this.debug('matchOne', file.length, pattern.length)\n\n  for (var fi = 0,\n      pi = 0,\n      fl = file.length,\n      pl = pattern.length\n      ; (fi < fl) && (pi < pl)\n      ; fi++, pi++) {\n    this.debug('matchOne loop')\n    var p = pattern[pi]\n    var f = file[fi]\n\n    this.debug(pattern, p, f)\n\n    // should be impossible.\n    // some invalid regexp stuff in the set.\n    /* istanbul ignore if */\n    if (p === false) return false\n\n    if (p === GLOBSTAR) {\n      this.debug('GLOBSTAR', [pattern, p, f])\n\n      // \"**\"\n      // a/**/b/**/c would match the following:\n      // a/b/x/y/z/c\n      // a/x/y/z/b/c\n      // a/b/x/b/x/c\n      // a/b/c\n      // To do this, take the rest of the pattern after\n      // the **, and see if it would match the file remainder.\n      // If so, return success.\n      // If not, the ** \"swallows\" a segment, and try again.\n      // This is recursively awful.\n      //\n      // a/**/b/**/c matching a/b/x/y/z/c\n      // - a matches a\n      // - doublestar\n      //   - matchOne(b/x/y/z/c, b/**/c)\n      //     - b matches b\n      //     - doublestar\n      //       - matchOne(x/y/z/c, c) -> no\n      //       - matchOne(y/z/c, c) -> no\n      //       - matchOne(z/c, c) -> no\n      //       - matchOne(c, c) yes, hit\n      var fr = fi\n      var pr = pi + 1\n      if (pr === pl) {\n        this.debug('** at the end')\n        // a ** at the end will just swallow the rest.\n        // We have found a match.\n        // however, it will not swallow /.x, unless\n        // options.dot is set.\n        // . and .. are *never* matched by **, for explosively\n        // exponential reasons.\n        for (; fi < fl; fi++) {\n          if (file[fi] === '.' || file[fi] === '..' ||\n            (!options.dot && file[fi].charAt(0) === '.')) return false\n        }\n        return true\n      }\n\n      // ok, let's see if we can swallow whatever we can.\n      while (fr < fl) {\n        var swallowee = file[fr]\n\n        this.debug('\\nglobstar while', file, fr, pattern, pr, swallowee)\n\n        // XXX remove this slice.  Just pass the start index.\n        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {\n          this.debug('globstar found match!', fr, fl, swallowee)\n          // found a match.\n          return true\n        } else {\n          // can't swallow \".\" or \"..\" ever.\n          // can only swallow \".foo\" when explicitly asked.\n          if (swallowee === '.' || swallowee === '..' ||\n            (!options.dot && swallowee.charAt(0) === '.')) {\n            this.debug('dot detected!', file, fr, pattern, pr)\n            break\n          }\n\n          // ** swallows a segment, and continue.\n          this.debug('globstar swallow a segment, and continue')\n          fr++\n        }\n      }\n\n      // no match was found.\n      // However, in partial mode, we can't say this is necessarily over.\n      // If there's more *pattern* left, then\n      /* istanbul ignore if */\n      if (partial) {\n        // ran out of file\n        this.debug('\\n>>> no match, partial?', file, fr, pattern, pr)\n        if (fr === fl) return true\n      }\n      return false\n    }\n\n    // something other than **\n    // non-magic patterns just have to match exactly\n    // patterns with magic have been turned into regexps.\n    var hit\n    if (typeof p === 'string') {\n      hit = f === p\n      this.debug('string match', p, f, hit)\n    } else {\n      hit = f.match(p)\n      this.debug('pattern match', p, f, hit)\n    }\n\n    if (!hit) return false\n  }\n\n  // Note: ending in / means that we'll get a final \"\"\n  // at the end of the pattern.  This can only match a\n  // corresponding \"\" at the end of the file.\n  // If the file ends in /, then it can only match a\n  // a pattern that ends in /, unless the pattern just\n  // doesn't have any more for it. But, a/b/ should *not*\n  // match \"a/b/*\", even though \"\" matches against the\n  // [^/]*? pattern, except in partial mode, where it might\n  // simply not be reached yet.\n  // However, a/b/ should still satisfy a/*\n\n  // now either we fell off the end of the pattern, or we're done.\n  if (fi === fl && pi === pl) {\n    // ran out of pattern and filename at the same time.\n    // an exact hit!\n    return true\n  } else if (fi === fl) {\n    // ran out of file, but still had pattern left.\n    // this is ok if we're doing the match as part of\n    // a glob fs traversal.\n    return partial\n  } else /* istanbul ignore else */ if (pi === pl) {\n    // ran out of pattern, still have file left.\n    // this is only acceptable if we're on the very last\n    // empty segment of a file with a trailing slash.\n    // a/* should match a/b/\n    return (fi === fl - 1) && (file[fi] === '')\n  }\n\n  // should be unreachable.\n  /* istanbul ignore next */\n  throw new Error('wtf?')\n}\n\n// replace stuff like \\* with *\nfunction globUnescape (s) {\n  return s.replace(/\\\\(.)/g, '$1')\n}\n\nfunction regExpEscape (s) {\n  return s.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&')\n}\n\n\n/***/ }),\n\n/***/ 4294:\n/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {\n\nmodule.exports = __nccwpck_require__(4219);\n\n\n/***/ }),\n\n/***/ 4219:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nvar net = __nccwpck_require__(1808);\nvar tls = __nccwpck_require__(4404);\nvar http = __nccwpck_require__(3685);\nvar https = __nccwpck_require__(5687);\nvar events = __nccwpck_require__(2361);\nvar assert = __nccwpck_require__(9491);\nvar util = __nccwpck_require__(3837);\n\n\nexports.httpOverHttp = httpOverHttp;\nexports.httpsOverHttp = httpsOverHttp;\nexports.httpOverHttps = httpOverHttps;\nexports.httpsOverHttps = httpsOverHttps;\n\n\nfunction httpOverHttp(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = http.request;\n  return agent;\n}\n\nfunction httpsOverHttp(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = http.request;\n  agent.createSocket = createSecureSocket;\n  agent.defaultPort = 443;\n  return agent;\n}\n\nfunction httpOverHttps(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = https.request;\n  return agent;\n}\n\nfunction httpsOverHttps(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = https.request;\n  agent.createSocket = createSecureSocket;\n  agent.defaultPort = 443;\n  return agent;\n}\n\n\nfunction TunnelingAgent(options) {\n  var self = this;\n  self.options = options || {};\n  self.proxyOptions = self.options.proxy || {};\n  self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;\n  self.requests = [];\n  self.sockets = [];\n\n  self.on('free', function onFree(socket, host, port, localAddress) {\n    var options = toOptions(host, port, localAddress);\n    for (var i = 0, len = self.requests.length; i < len; ++i) {\n      var pending = self.requests[i];\n      if (pending.host === options.host && pending.port === options.port) {\n        // Detect the request to connect same origin server,\n        // reuse the connection.\n        self.requests.splice(i, 1);\n        pending.request.onSocket(socket);\n        return;\n      }\n    }\n    socket.destroy();\n    self.removeSocket(socket);\n  });\n}\nutil.inherits(TunnelingAgent, events.EventEmitter);\n\nTunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {\n  var self = this;\n  var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));\n\n  if (self.sockets.length >= this.maxSockets) {\n    // We are over limit so we'll add it to the queue.\n    self.requests.push(options);\n    return;\n  }\n\n  // If we are under maxSockets create a new one.\n  self.createSocket(options, function(socket) {\n    socket.on('free', onFree);\n    socket.on('close', onCloseOrRemove);\n    socket.on('agentRemove', onCloseOrRemove);\n    req.onSocket(socket);\n\n    function onFree() {\n      self.emit('free', socket, options);\n    }\n\n    function onCloseOrRemove(err) {\n      self.removeSocket(socket);\n      socket.removeListener('free', onFree);\n      socket.removeListener('close', onCloseOrRemove);\n      socket.removeListener('agentRemove', onCloseOrRemove);\n    }\n  });\n};\n\nTunnelingAgent.prototype.createSocket = function createSocket(options, cb) {\n  var self = this;\n  var placeholder = {};\n  self.sockets.push(placeholder);\n\n  var connectOptions = mergeOptions({}, self.proxyOptions, {\n    method: 'CONNECT',\n    path: options.host + ':' + options.port,\n    agent: false,\n    headers: {\n      host: options.host + ':' + options.port\n    }\n  });\n  if (options.localAddress) {\n    connectOptions.localAddress = options.localAddress;\n  }\n  if (connectOptions.proxyAuth) {\n    connectOptions.headers = connectOptions.headers || {};\n    connectOptions.headers['Proxy-Authorization'] = 'Basic ' +\n        new Buffer(connectOptions.proxyAuth).toString('base64');\n  }\n\n  debug('making CONNECT request');\n  var connectReq = self.request(connectOptions);\n  connectReq.useChunkedEncodingByDefault = false; // for v0.6\n  connectReq.once('response', onResponse); // for v0.6\n  connectReq.once('upgrade', onUpgrade);   // for v0.6\n  connectReq.once('connect', onConnect);   // for v0.7 or later\n  connectReq.once('error', onError);\n  connectReq.end();\n\n  function onResponse(res) {\n    // Very hacky. This is necessary to avoid http-parser leaks.\n    res.upgrade = true;\n  }\n\n  function onUpgrade(res, socket, head) {\n    // Hacky.\n    process.nextTick(function() {\n      onConnect(res, socket, head);\n    });\n  }\n\n  function onConnect(res, socket, head) {\n    connectReq.removeAllListeners();\n    socket.removeAllListeners();\n\n    if (res.statusCode !== 200) {\n      debug('tunneling socket could not be established, statusCode=%d',\n        res.statusCode);\n      socket.destroy();\n      var error = new Error('tunneling socket could not be established, ' +\n        'statusCode=' + res.statusCode);\n      error.code = 'ECONNRESET';\n      options.request.emit('error', error);\n      self.removeSocket(placeholder);\n      return;\n    }\n    if (head.length > 0) {\n      debug('got illegal response body from proxy');\n      socket.destroy();\n      var error = new Error('got illegal response body from proxy');\n      error.code = 'ECONNRESET';\n      options.request.emit('error', error);\n      self.removeSocket(placeholder);\n      return;\n    }\n    debug('tunneling connection has established');\n    self.sockets[self.sockets.indexOf(placeholder)] = socket;\n    return cb(socket);\n  }\n\n  function onError(cause) {\n    connectReq.removeAllListeners();\n\n    debug('tunneling socket could not be established, cause=%s\\n',\n          cause.message, cause.stack);\n    var error = new Error('tunneling socket could not be established, ' +\n                          'cause=' + cause.message);\n    error.code = 'ECONNRESET';\n    options.request.emit('error', error);\n    self.removeSocket(placeholder);\n  }\n};\n\nTunnelingAgent.prototype.removeSocket = function removeSocket(socket) {\n  var pos = this.sockets.indexOf(socket)\n  if (pos === -1) {\n    return;\n  }\n  this.sockets.splice(pos, 1);\n\n  var pending = this.requests.shift();\n  if (pending) {\n    // If we have pending requests and a socket gets closed a new one\n    // needs to be created to take over in the pool for the one that closed.\n    this.createSocket(pending, function(socket) {\n      pending.request.onSocket(socket);\n    });\n  }\n};\n\nfunction createSecureSocket(options, cb) {\n  var self = this;\n  TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {\n    var hostHeader = options.request.getHeader('host');\n    var tlsOptions = mergeOptions({}, self.options, {\n      socket: socket,\n      servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host\n    });\n\n    // 0 is dummy port for v0.6\n    var secureSocket = tls.connect(0, tlsOptions);\n    self.sockets[self.sockets.indexOf(socket)] = secureSocket;\n    cb(secureSocket);\n  });\n}\n\n\nfunction toOptions(host, port, localAddress) {\n  if (typeof host === 'string') { // since v0.10\n    return {\n      host: host,\n      port: port,\n      localAddress: localAddress\n    };\n  }\n  return host; // for v0.11 or later\n}\n\nfunction mergeOptions(target) {\n  for (var i = 1, len = arguments.length; i < len; ++i) {\n    var overrides = arguments[i];\n    if (typeof overrides === 'object') {\n      var keys = Object.keys(overrides);\n      for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {\n        var k = keys[j];\n        if (overrides[k] !== undefined) {\n          target[k] = overrides[k];\n        }\n      }\n    }\n  }\n  return target;\n}\n\n\nvar debug;\nif (process.env.NODE_DEBUG && /\\btunnel\\b/.test(process.env.NODE_DEBUG)) {\n  debug = function() {\n    var args = Array.prototype.slice.call(arguments);\n    if (typeof args[0] === 'string') {\n      args[0] = 'TUNNEL: ' + args[0];\n    } else {\n      args.unshift('TUNNEL:');\n    }\n    console.error.apply(console, args);\n  }\n} else {\n  debug = function() {};\n}\nexports.debug = debug; // for test\n\n\n/***/ }),\n\n/***/ 5840:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nObject.defineProperty(exports, \"v1\", ({\n  enumerable: true,\n  get: function () {\n    return _v.default;\n  }\n}));\nObject.defineProperty(exports, \"v3\", ({\n  enumerable: true,\n  get: function () {\n    return _v2.default;\n  }\n}));\nObject.defineProperty(exports, \"v4\", ({\n  enumerable: true,\n  get: function () {\n    return _v3.default;\n  }\n}));\nObject.defineProperty(exports, \"v5\", ({\n  enumerable: true,\n  get: function () {\n    return _v4.default;\n  }\n}));\nObject.defineProperty(exports, \"NIL\", ({\n  enumerable: true,\n  get: function () {\n    return _nil.default;\n  }\n}));\nObject.defineProperty(exports, \"version\", ({\n  enumerable: true,\n  get: function () {\n    return _version.default;\n  }\n}));\nObject.defineProperty(exports, \"validate\", ({\n  enumerable: true,\n  get: function () {\n    return _validate.default;\n  }\n}));\nObject.defineProperty(exports, \"stringify\", ({\n  enumerable: true,\n  get: function () {\n    return _stringify.default;\n  }\n}));\nObject.defineProperty(exports, \"parse\", ({\n  enumerable: true,\n  get: function () {\n    return _parse.default;\n  }\n}));\n\nvar _v = _interopRequireDefault(__nccwpck_require__(8628));\n\nvar _v2 = _interopRequireDefault(__nccwpck_require__(6409));\n\nvar _v3 = _interopRequireDefault(__nccwpck_require__(5122));\n\nvar _v4 = _interopRequireDefault(__nccwpck_require__(9120));\n\nvar _nil = _interopRequireDefault(__nccwpck_require__(5332));\n\nvar _version = _interopRequireDefault(__nccwpck_require__(1595));\n\nvar _validate = _interopRequireDefault(__nccwpck_require__(6900));\n\nvar _stringify = _interopRequireDefault(__nccwpck_require__(8950));\n\nvar _parse = _interopRequireDefault(__nccwpck_require__(2746));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/***/ }),\n\n/***/ 4569:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _crypto = _interopRequireDefault(__nccwpck_require__(6113));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction md5(bytes) {\n  if (Array.isArray(bytes)) {\n    bytes = Buffer.from(bytes);\n  } else if (typeof bytes === 'string') {\n    bytes = Buffer.from(bytes, 'utf8');\n  }\n\n  return _crypto.default.createHash('md5').update(bytes).digest();\n}\n\nvar _default = md5;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 5332:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\nvar _default = '00000000-0000-0000-0000-000000000000';\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 2746:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _validate = _interopRequireDefault(__nccwpck_require__(6900));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction parse(uuid) {\n  if (!(0, _validate.default)(uuid)) {\n    throw TypeError('Invalid UUID');\n  }\n\n  let v;\n  const arr = new Uint8Array(16); // Parse ########-....-....-....-............\n\n  arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;\n  arr[1] = v >>> 16 & 0xff;\n  arr[2] = v >>> 8 & 0xff;\n  arr[3] = v & 0xff; // Parse ........-####-....-....-............\n\n  arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;\n  arr[5] = v & 0xff; // Parse ........-....-####-....-............\n\n  arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;\n  arr[7] = v & 0xff; // Parse ........-....-....-####-............\n\n  arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;\n  arr[9] = v & 0xff; // Parse ........-....-....-....-############\n  // (Use \"/\" to avoid 32-bit truncation when bit-shifting high-order bytes)\n\n  arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;\n  arr[11] = v / 0x100000000 & 0xff;\n  arr[12] = v >>> 24 & 0xff;\n  arr[13] = v >>> 16 & 0xff;\n  arr[14] = v >>> 8 & 0xff;\n  arr[15] = v & 0xff;\n  return arr;\n}\n\nvar _default = parse;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 814:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\nvar _default = /^(?:[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;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 807:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = rng;\n\nvar _crypto = _interopRequireDefault(__nccwpck_require__(6113));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nconst rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate\n\nlet poolPtr = rnds8Pool.length;\n\nfunction rng() {\n  if (poolPtr > rnds8Pool.length - 16) {\n    _crypto.default.randomFillSync(rnds8Pool);\n\n    poolPtr = 0;\n  }\n\n  return rnds8Pool.slice(poolPtr, poolPtr += 16);\n}\n\n/***/ }),\n\n/***/ 5274:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _crypto = _interopRequireDefault(__nccwpck_require__(6113));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction sha1(bytes) {\n  if (Array.isArray(bytes)) {\n    bytes = Buffer.from(bytes);\n  } else if (typeof bytes === 'string') {\n    bytes = Buffer.from(bytes, 'utf8');\n  }\n\n  return _crypto.default.createHash('sha1').update(bytes).digest();\n}\n\nvar _default = sha1;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 8950:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _validate = _interopRequireDefault(__nccwpck_require__(6900));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nconst byteToHex = [];\n\nfor (let i = 0; i < 256; ++i) {\n  byteToHex.push((i + 0x100).toString(16).substr(1));\n}\n\nfunction stringify(arr, offset = 0) {\n  // Note: Be careful editing this code!  It's been tuned for performance\n  // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n  const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID.  If this throws, it's likely due to one\n  // of the following:\n  // - One or more input array values don't map to a hex octet (leading to\n  // \"undefined\" in the uuid)\n  // - Invalid input values for the RFC `version` or `variant` fields\n\n  if (!(0, _validate.default)(uuid)) {\n    throw TypeError('Stringified UUID is invalid');\n  }\n\n  return uuid;\n}\n\nvar _default = stringify;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 8628:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _rng = _interopRequireDefault(__nccwpck_require__(807));\n\nvar _stringify = _interopRequireDefault(__nccwpck_require__(8950));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// **`v1()` - Generate time-based UUID**\n//\n// Inspired by https://github.com/LiosK/UUID.js\n// and http://docs.python.org/library/uuid.html\nlet _nodeId;\n\nlet _clockseq; // Previous uuid creation time\n\n\nlet _lastMSecs = 0;\nlet _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details\n\nfunction v1(options, buf, offset) {\n  let i = buf && offset || 0;\n  const b = buf || new Array(16);\n  options = options || {};\n  let node = options.node || _nodeId;\n  let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not\n  // specified.  We do this lazily to minimize issues related to insufficient\n  // system entropy.  See #189\n\n  if (node == null || clockseq == null) {\n    const seedBytes = options.random || (options.rng || _rng.default)();\n\n    if (node == null) {\n      // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)\n      node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];\n    }\n\n    if (clockseq == null) {\n      // Per 4.2.2, randomize (14 bit) clockseq\n      clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;\n    }\n  } // UUID timestamps are 100 nano-second units since the Gregorian epoch,\n  // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so\n  // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'\n  // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.\n\n\n  let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock\n  // cycle to simulate higher resolution clock\n\n  let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)\n\n  const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression\n\n  if (dt < 0 && options.clockseq === undefined) {\n    clockseq = clockseq + 1 & 0x3fff;\n  } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new\n  // time interval\n\n\n  if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {\n    nsecs = 0;\n  } // Per 4.2.1.2 Throw error if too many uuids are requested\n\n\n  if (nsecs >= 10000) {\n    throw new Error(\"uuid.v1(): Can't create more than 10M uuids/sec\");\n  }\n\n  _lastMSecs = msecs;\n  _lastNSecs = nsecs;\n  _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch\n\n  msecs += 12219292800000; // `time_low`\n\n  const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n  b[i++] = tl >>> 24 & 0xff;\n  b[i++] = tl >>> 16 & 0xff;\n  b[i++] = tl >>> 8 & 0xff;\n  b[i++] = tl & 0xff; // `time_mid`\n\n  const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;\n  b[i++] = tmh >>> 8 & 0xff;\n  b[i++] = tmh & 0xff; // `time_high_and_version`\n\n  b[i++] = tmh >>> 24 & 0xf | 0x10; // include version\n\n  b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)\n\n  b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`\n\n  b[i++] = clockseq & 0xff; // `node`\n\n  for (let n = 0; n < 6; ++n) {\n    b[i + n] = node[n];\n  }\n\n  return buf || (0, _stringify.default)(b);\n}\n\nvar _default = v1;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 6409:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _v = _interopRequireDefault(__nccwpck_require__(5998));\n\nvar _md = _interopRequireDefault(__nccwpck_require__(4569));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nconst v3 = (0, _v.default)('v3', 0x30, _md.default);\nvar _default = v3;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 5998:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = _default;\nexports.URL = exports.DNS = void 0;\n\nvar _stringify = _interopRequireDefault(__nccwpck_require__(8950));\n\nvar _parse = _interopRequireDefault(__nccwpck_require__(2746));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction stringToBytes(str) {\n  str = unescape(encodeURIComponent(str)); // UTF8 escape\n\n  const bytes = [];\n\n  for (let i = 0; i < str.length; ++i) {\n    bytes.push(str.charCodeAt(i));\n  }\n\n  return bytes;\n}\n\nconst DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\nexports.DNS = DNS;\nconst URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\nexports.URL = URL;\n\nfunction _default(name, version, hashfunc) {\n  function generateUUID(value, namespace, buf, offset) {\n    if (typeof value === 'string') {\n      value = stringToBytes(value);\n    }\n\n    if (typeof namespace === 'string') {\n      namespace = (0, _parse.default)(namespace);\n    }\n\n    if (namespace.length !== 16) {\n      throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');\n    } // Compute hash of namespace and value, Per 4.3\n    // Future: Use spread syntax when supported on all platforms, e.g. `bytes =\n    // hashfunc([...namespace, ... value])`\n\n\n    let bytes = new Uint8Array(16 + value.length);\n    bytes.set(namespace);\n    bytes.set(value, namespace.length);\n    bytes = hashfunc(bytes);\n    bytes[6] = bytes[6] & 0x0f | version;\n    bytes[8] = bytes[8] & 0x3f | 0x80;\n\n    if (buf) {\n      offset = offset || 0;\n\n      for (let i = 0; i < 16; ++i) {\n        buf[offset + i] = bytes[i];\n      }\n\n      return buf;\n    }\n\n    return (0, _stringify.default)(bytes);\n  } // Function#name is not settable on some platforms (#270)\n\n\n  try {\n    generateUUID.name = name; // eslint-disable-next-line no-empty\n  } catch (err) {} // For CommonJS default export support\n\n\n  generateUUID.DNS = DNS;\n  generateUUID.URL = URL;\n  return generateUUID;\n}\n\n/***/ }),\n\n/***/ 5122:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _rng = _interopRequireDefault(__nccwpck_require__(807));\n\nvar _stringify = _interopRequireDefault(__nccwpck_require__(8950));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction v4(options, buf, offset) {\n  options = options || {};\n\n  const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\n\n  rnds[6] = rnds[6] & 0x0f | 0x40;\n  rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided\n\n  if (buf) {\n    offset = offset || 0;\n\n    for (let i = 0; i < 16; ++i) {\n      buf[offset + i] = rnds[i];\n    }\n\n    return buf;\n  }\n\n  return (0, _stringify.default)(rnds);\n}\n\nvar _default = v4;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 9120:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _v = _interopRequireDefault(__nccwpck_require__(5998));\n\nvar _sha = _interopRequireDefault(__nccwpck_require__(5274));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nconst v5 = (0, _v.default)('v5', 0x50, _sha.default);\nvar _default = v5;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 6900:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _regex = _interopRequireDefault(__nccwpck_require__(814));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction validate(uuid) {\n  return typeof uuid === 'string' && _regex.default.test(uuid);\n}\n\nvar _default = validate;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 1595:\n/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({\n  value: true\n}));\nexports[\"default\"] = void 0;\n\nvar _validate = _interopRequireDefault(__nccwpck_require__(6900));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction version(uuid) {\n  if (!(0, _validate.default)(uuid)) {\n    throw TypeError('Invalid UUID');\n  }\n\n  return parseInt(uuid.substr(14, 1), 16);\n}\n\nvar _default = version;\nexports[\"default\"] = _default;\n\n/***/ }),\n\n/***/ 9491:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"assert\");\n\n/***/ }),\n\n/***/ 6113:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"crypto\");\n\n/***/ }),\n\n/***/ 2361:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"events\");\n\n/***/ }),\n\n/***/ 7147:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"fs\");\n\n/***/ }),\n\n/***/ 3685:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"http\");\n\n/***/ }),\n\n/***/ 5687:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"https\");\n\n/***/ }),\n\n/***/ 1808:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"net\");\n\n/***/ }),\n\n/***/ 2037:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"os\");\n\n/***/ }),\n\n/***/ 1017:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"path\");\n\n/***/ }),\n\n/***/ 2781:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"stream\");\n\n/***/ }),\n\n/***/ 4404:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"tls\");\n\n/***/ }),\n\n/***/ 3837:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"util\");\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __nccwpck_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \t\tif (cachedModule !== undefined) {\n/******/ \t\t\treturn cachedModule.exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tvar threw = true;\n/******/ \t\ttry {\n/******/ \t\t\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __nccwpck_require__);\n/******/ \t\t\tthrew = false;\n/******/ \t\t} finally {\n/******/ \t\t\tif(threw) delete __webpack_module_cache__[moduleId];\n/******/ \t\t}\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat */\n/******/\n/******/ \tif (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + \"/\";\n/******/\n/************************************************************************/\n/******/\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \t// This entry module is referenced by other modules so it can't be inlined\n/******/ \tvar __webpack_exports__ = __nccwpck_require__(2627);\n/******/ \tmodule.exports = __webpack_exports__;\n/******/\n/******/ })()\n;\n"
  },
  {
    "path": "pkg/runner/job_executor.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype jobInfo interface {\n\tmatrix() map[string]interface{}\n\tsteps() []*model.Step\n\tstartContainer() common.Executor\n\tstopContainer() common.Executor\n\tcloseContainer() common.Executor\n\tinterpolateOutputs() common.Executor\n\tresult(result string)\n}\n\n//nolint:contextcheck\nfunc newJobExecutor(info jobInfo, sf stepFactory, rc *RunContext) common.Executor {\n\tsteps := make([]common.Executor, 0)\n\tpreSteps := make([]common.Executor, 0)\n\tvar postExecutor common.Executor\n\n\tsteps = append(steps, func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\tif len(info.matrix()) > 0 {\n\t\t\tlogger.Infof(\"\\U0001F9EA  Matrix: %v\", info.matrix())\n\t\t}\n\t\treturn nil\n\t})\n\n\tinfoSteps := info.steps()\n\n\tif len(infoSteps) == 0 {\n\t\treturn common.NewDebugExecutor(\"No steps found\")\n\t}\n\n\tpreSteps = append(preSteps, func(ctx context.Context) error {\n\t\t// Have to be skipped for some Tests\n\t\tif rc.Run == nil {\n\t\t\treturn nil\n\t\t}\n\t\trc.ExprEval = rc.NewExpressionEvaluator(ctx)\n\t\t// evaluate environment variables since they can contain\n\t\t// GitHub's special environment variables.\n\t\tfor k, v := range rc.GetEnv() {\n\t\t\trc.Env[k] = rc.ExprEval.Interpolate(ctx, v)\n\t\t}\n\t\treturn nil\n\t})\n\n\tvar setJobError = func(ctx context.Context, err error) error {\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t\tlogger := common.Logger(ctx)\n\t\tlogger.Errorf(\"%v\", err)\n\t\tcommon.SetJobError(ctx, err)\n\t\treturn err\n\t}\n\n\tfor i, stepModel := range infoSteps {\n\t\tif stepModel == nil {\n\t\t\treturn func(_ context.Context) error {\n\t\t\t\treturn fmt.Errorf(\"invalid Step %v: missing run or uses key\", i)\n\t\t\t}\n\t\t}\n\t\tif stepModel.ID == \"\" {\n\t\t\tstepModel.ID = fmt.Sprintf(\"%d\", i)\n\t\t}\n\n\t\tstep, err := sf.newStep(stepModel, rc)\n\n\t\tif err != nil {\n\t\t\treturn common.NewErrorExecutor(err)\n\t\t}\n\n\t\tpreSteps = append(preSteps, useStepLogger(rc, stepModel, stepStagePre, step.pre().ThenError(setJobError)))\n\n\t\tstepExec := step.main()\n\t\tsteps = append(steps, useStepLogger(rc, stepModel, stepStageMain, func(ctx context.Context) error {\n\t\t\terr := stepExec(ctx)\n\t\t\tif err != nil {\n\t\t\t\t_ = setJobError(ctx, err)\n\t\t\t} else if ctx.Err() != nil {\n\t\t\t\t_ = setJobError(ctx, ctx.Err())\n\t\t\t}\n\t\t\treturn nil\n\t\t}))\n\n\t\tpostExec := useStepLogger(rc, stepModel, stepStagePost, step.post().ThenError(setJobError))\n\t\tif postExecutor != nil {\n\t\t\t// run the post executor in reverse order\n\t\t\tpostExecutor = postExec.Finally(postExecutor)\n\t\t} else {\n\t\t\tpostExecutor = postExec\n\t\t}\n\t}\n\n\tvar stopContainerExecutor common.Executor = func(ctx context.Context) error {\n\t\tjobError := common.JobError(ctx)\n\t\tvar err error\n\t\tif rc.Config.AutoRemove || jobError == nil {\n\t\t\t// always allow 1 min for stopping and removing the runner, even if we were cancelled\n\t\t\tctx, cancel := context.WithTimeout(common.WithLogger(context.Background(), common.Logger(ctx)), time.Minute)\n\t\t\tdefer cancel()\n\n\t\t\tlogger := common.Logger(ctx)\n\t\t\tlogger.Infof(\"Cleaning up container for job %s\", rc.JobName)\n\t\t\tif err = info.stopContainer()(ctx); err != nil {\n\t\t\t\tlogger.Errorf(\"Error while stop job container: %v\", err)\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n\n\tvar setJobResultExecutor common.Executor = func(ctx context.Context) error {\n\t\tjobError := common.JobError(ctx)\n\t\tsetJobResult(ctx, info, rc, jobError == nil)\n\t\tsetJobOutputs(ctx, rc)\n\t\treturn nil\n\t}\n\n\tpipeline := make([]common.Executor, 0)\n\tpipeline = append(pipeline, preSteps...)\n\tpipeline = append(pipeline, steps...)\n\n\treturn common.NewPipelineExecutor(\n\t\tcommon.NewFieldExecutor(\"step\", \"Set up job\", common.NewFieldExecutor(\"stepid\", []string{\"--setup-job\"},\n\t\t\tcommon.NewPipelineExecutor(common.NewInfoExecutor(\"\\u2B50 Run Set up job\"), info.startContainer(), rc.InitializeNodeTool()).\n\t\t\t\tThen(common.NewFieldExecutor(\"stepResult\", model.StepStatusSuccess, common.NewInfoExecutor(\"  \\u2705  Success - Set up job\"))).\n\t\t\t\tThenError(setJobError).OnError(common.NewFieldExecutor(\"stepResult\", model.StepStatusFailure, common.NewInfoExecutor(\"  \\u274C  Failure - Set up job\"))))),\n\t\tcommon.NewPipelineExecutor(pipeline...).\n\t\t\tFinally(func(ctx context.Context) error { //nolint:contextcheck\n\t\t\t\tvar cancel context.CancelFunc\n\t\t\t\tif ctx.Err() == context.Canceled {\n\t\t\t\t\t// in case of an aborted run, we still should execute the\n\t\t\t\t\t// post steps to allow cleanup.\n\t\t\t\t\tctx, cancel = context.WithTimeout(common.WithLogger(context.Background(), common.Logger(ctx)), 5*time.Minute)\n\t\t\t\t\tdefer cancel()\n\t\t\t\t}\n\t\t\t\treturn postExecutor(ctx)\n\t\t\t}).\n\t\t\tFinally(common.NewFieldExecutor(\"step\", \"Complete job\", common.NewFieldExecutor(\"stepid\", []string{\"--complete-job\"},\n\t\t\t\tcommon.NewInfoExecutor(\"\\u2B50 Run Complete job\").\n\t\t\t\t\tFinally(stopContainerExecutor).\n\t\t\t\t\tFinally(\n\t\t\t\t\t\tinfo.interpolateOutputs().Finally(info.closeContainer()).Then(common.NewFieldExecutor(\"stepResult\", model.StepStatusSuccess, common.NewInfoExecutor(\"  \\u2705  Success - Complete job\"))).\n\t\t\t\t\t\t\tOnError(common.NewFieldExecutor(\"stepResult\", model.StepStatusFailure, common.NewInfoExecutor(\"  \\u274C  Failure - Complete job\"))),\n\t\t\t\t\t))))).Finally(setJobResultExecutor)\n}\n\nfunc setJobResult(ctx context.Context, info jobInfo, rc *RunContext, success bool) {\n\tlogger := common.Logger(ctx)\n\n\tjobResult := \"success\"\n\t// we have only one result for a whole matrix build, so we need\n\t// to keep an existing result state if we run a matrix\n\tif len(info.matrix()) > 0 && rc.Run.Job().Result != \"\" {\n\t\tjobResult = rc.Run.Job().Result\n\t}\n\n\tif !success {\n\t\tjobResult = \"failure\"\n\t}\n\n\tinfo.result(jobResult)\n\tif rc.caller != nil {\n\t\t// set reusable workflow job result\n\t\trc.caller.runContext.result(jobResult)\n\t}\n\n\tjobResultMessage := \"succeeded\"\n\tif jobResult != \"success\" {\n\t\tjobResultMessage = \"failed\"\n\t}\n\n\tlogger.WithField(\"jobResult\", jobResult).Infof(\"\\U0001F3C1  Job %s\", jobResultMessage)\n}\n\nfunc setJobOutputs(ctx context.Context, rc *RunContext) {\n\tif rc.caller != nil {\n\t\t// map outputs for reusable workflows\n\t\tcallerOutputs := make(map[string]string)\n\n\t\tee := rc.NewExpressionEvaluator(ctx)\n\n\t\tfor k, v := range rc.Run.Workflow.WorkflowCallConfig().Outputs {\n\t\t\tcallerOutputs[k] = ee.Interpolate(ctx, ee.Interpolate(ctx, v.Value))\n\t\t}\n\n\t\trc.caller.runContext.Run.Job().Outputs = callerOutputs\n\t}\n}\n\nfunc useStepLogger(rc *RunContext, stepModel *model.Step, stage stepStage, executor common.Executor) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tctx = withStepLogger(ctx, stepModel.ID, rc.ExprEval.Interpolate(ctx, stepModel.String()), stage.String())\n\n\t\trawLogger := common.Logger(ctx).WithField(\"raw_output\", true)\n\t\tlogWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool {\n\t\t\tif rc.Config.LogOutput {\n\t\t\t\trawLogger.Infof(\"%s\", s)\n\t\t\t} else {\n\t\t\t\trawLogger.Debugf(\"%s\", s)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\n\t\toldout, olderr := rc.JobContainer.ReplaceLogWriter(logWriter, logWriter)\n\t\tdefer rc.JobContainer.ReplaceLogWriter(oldout, olderr)\n\n\t\treturn executor(ctx)\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/job_executor_test.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n)\n\nfunc TestJobExecutor(t *testing.T) {\n\ttables := []TestJobFileInfo{\n\t\t{workdir, \"uses-and-run-in-one-step\", \"push\", \"Invalid run/uses syntax for job:test step:Test\", platforms, secrets},\n\t\t{workdir, \"uses-github-empty\", \"push\", \"Expected format {org}/{repo}[/path]@ref\", platforms, secrets},\n\t\t{workdir, \"uses-github-noref\", \"push\", \"Expected format {org}/{repo}[/path]@ref\", platforms, secrets},\n\t\t{workdir, \"uses-github-root\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-github-path\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-docker-url\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-github-full-sha\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-github-short-sha\", \"push\", \"Unable to resolve action `actions/hello-world-docker-action@b136eb8`, the provided ref `b136eb8` is the shortened version of a commit SHA, which is not supported. Please use the full commit SHA `b136eb8894c5cb1dd5807da824be97ccdf9b5423` instead\", platforms, secrets},\n\t\t{workdir, \"job-nil-step\", \"push\", \"invalid Step 0: missing run or uses key\", platforms, secrets},\n\t}\n\t// These tests are sufficient to only check syntax.\n\tctx := common.WithDryrun(context.Background(), true)\n\tfor _, table := range tables {\n\t\tt.Run(table.workflowPath, func(t *testing.T) {\n\t\t\ttable.runTest(ctx, t, &Config{})\n\t\t})\n\t}\n}\n\ntype jobInfoMock struct {\n\tmock.Mock\n}\n\nfunc (jim *jobInfoMock) matrix() map[string]interface{} {\n\targs := jim.Called()\n\treturn args.Get(0).(map[string]interface{})\n}\n\nfunc (jim *jobInfoMock) steps() []*model.Step {\n\targs := jim.Called()\n\n\treturn args.Get(0).([]*model.Step)\n}\n\nfunc (jim *jobInfoMock) startContainer() common.Executor {\n\targs := jim.Called()\n\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (jim *jobInfoMock) stopContainer() common.Executor {\n\targs := jim.Called()\n\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (jim *jobInfoMock) closeContainer() common.Executor {\n\targs := jim.Called()\n\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (jim *jobInfoMock) interpolateOutputs() common.Executor {\n\targs := jim.Called()\n\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (jim *jobInfoMock) result(result string) {\n\tjim.Called(result)\n}\n\ntype jobContainerMock struct {\n\tcontainer.Container\n\tcontainer.LinuxContainerEnvironmentExtensions\n}\n\nfunc (jcm *jobContainerMock) ReplaceLogWriter(_, _ io.Writer) (io.Writer, io.Writer) {\n\treturn nil, nil\n}\n\ntype stepFactoryMock struct {\n\tmock.Mock\n}\n\nfunc (sfm *stepFactoryMock) newStep(model *model.Step, rc *RunContext) (step, error) {\n\targs := sfm.Called(model, rc)\n\treturn args.Get(0).(step), args.Error(1)\n}\n\nfunc TestNewJobExecutor(t *testing.T) {\n\ttable := []struct {\n\t\tname          string\n\t\tsteps         []*model.Step\n\t\tpreSteps      []bool\n\t\tpostSteps     []bool\n\t\texecutedSteps []string\n\t\tresult        string\n\t\thasError      bool\n\t}{\n\t\t{\n\t\t\tname:          \"zeroSteps\",\n\t\t\tsteps:         []*model.Step{},\n\t\t\tpreSteps:      []bool{},\n\t\t\tpostSteps:     []bool{},\n\t\t\texecutedSteps: []string{},\n\t\t\tresult:        \"success\",\n\t\t\thasError:      false,\n\t\t},\n\t\t{\n\t\t\tname: \"stepWithoutPrePost\",\n\t\t\tsteps: []*model.Step{{\n\t\t\t\tID: \"1\",\n\t\t\t}},\n\t\t\tpreSteps:  []bool{false},\n\t\t\tpostSteps: []bool{false},\n\t\t\texecutedSteps: []string{\n\t\t\t\t\"startContainer\",\n\t\t\t\t\"step1\",\n\t\t\t\t\"stopContainer\",\n\t\t\t\t\"interpolateOutputs\",\n\t\t\t\t\"closeContainer\",\n\t\t\t},\n\t\t\tresult:   \"success\",\n\t\t\thasError: false,\n\t\t},\n\t\t{\n\t\t\tname: \"stepWithFailure\",\n\t\t\tsteps: []*model.Step{{\n\t\t\t\tID: \"1\",\n\t\t\t}},\n\t\t\tpreSteps:  []bool{false},\n\t\t\tpostSteps: []bool{false},\n\t\t\texecutedSteps: []string{\n\t\t\t\t\"startContainer\",\n\t\t\t\t\"step1\",\n\t\t\t\t\"interpolateOutputs\",\n\t\t\t\t\"closeContainer\",\n\t\t\t},\n\t\t\tresult:   \"failure\",\n\t\t\thasError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"stepWithPre\",\n\t\t\tsteps: []*model.Step{{\n\t\t\t\tID: \"1\",\n\t\t\t}},\n\t\t\tpreSteps:  []bool{true},\n\t\t\tpostSteps: []bool{false},\n\t\t\texecutedSteps: []string{\n\t\t\t\t\"startContainer\",\n\t\t\t\t\"pre1\",\n\t\t\t\t\"step1\",\n\t\t\t\t\"stopContainer\",\n\t\t\t\t\"interpolateOutputs\",\n\t\t\t\t\"closeContainer\",\n\t\t\t},\n\t\t\tresult:   \"success\",\n\t\t\thasError: false,\n\t\t},\n\t\t{\n\t\t\tname: \"stepWithPost\",\n\t\t\tsteps: []*model.Step{{\n\t\t\t\tID: \"1\",\n\t\t\t}},\n\t\t\tpreSteps:  []bool{false},\n\t\t\tpostSteps: []bool{true},\n\t\t\texecutedSteps: []string{\n\t\t\t\t\"startContainer\",\n\t\t\t\t\"step1\",\n\t\t\t\t\"post1\",\n\t\t\t\t\"stopContainer\",\n\t\t\t\t\"interpolateOutputs\",\n\t\t\t\t\"closeContainer\",\n\t\t\t},\n\t\t\tresult:   \"success\",\n\t\t\thasError: false,\n\t\t},\n\t\t{\n\t\t\tname: \"stepWithPreAndPost\",\n\t\t\tsteps: []*model.Step{{\n\t\t\t\tID: \"1\",\n\t\t\t}},\n\t\t\tpreSteps:  []bool{true},\n\t\t\tpostSteps: []bool{true},\n\t\t\texecutedSteps: []string{\n\t\t\t\t\"startContainer\",\n\t\t\t\t\"pre1\",\n\t\t\t\t\"step1\",\n\t\t\t\t\"post1\",\n\t\t\t\t\"stopContainer\",\n\t\t\t\t\"interpolateOutputs\",\n\t\t\t\t\"closeContainer\",\n\t\t\t},\n\t\t\tresult:   \"success\",\n\t\t\thasError: false,\n\t\t},\n\t\t{\n\t\t\tname: \"stepsWithPreAndPost\",\n\t\t\tsteps: []*model.Step{{\n\t\t\t\tID: \"1\",\n\t\t\t}, {\n\t\t\t\tID: \"2\",\n\t\t\t}, {\n\t\t\t\tID: \"3\",\n\t\t\t}},\n\t\t\tpreSteps:  []bool{true, false, true},\n\t\t\tpostSteps: []bool{false, true, true},\n\t\t\texecutedSteps: []string{\n\t\t\t\t\"startContainer\",\n\t\t\t\t\"pre1\",\n\t\t\t\t\"pre3\",\n\t\t\t\t\"step1\",\n\t\t\t\t\"step2\",\n\t\t\t\t\"step3\",\n\t\t\t\t\"post3\",\n\t\t\t\t\"post2\",\n\t\t\t\t\"stopContainer\",\n\t\t\t\t\"interpolateOutputs\",\n\t\t\t\t\"closeContainer\",\n\t\t\t},\n\t\t\tresult:   \"success\",\n\t\t\thasError: false,\n\t\t},\n\t}\n\n\tcontains := func(needle string, haystack []string) bool {\n\t\tfor _, item := range haystack {\n\t\t\tif item == needle {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tfmt.Printf(\"::group::%s\\n\", tt.name)\n\n\t\t\tctx := common.WithJobErrorContainer(context.Background())\n\t\t\tjim := &jobInfoMock{}\n\t\t\tsfm := &stepFactoryMock{}\n\t\t\trc := &RunContext{\n\t\t\t\tJobContainer: &jobContainerMock{},\n\t\t\t\tRun: &model.Run{\n\t\t\t\t\tJobID: \"test\",\n\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\"test\": {},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig:           &Config{},\n\t\t\t\tnodeToolFullPath: \"node\",\n\t\t\t}\n\t\t\trc.ExprEval = rc.NewExpressionEvaluator(ctx)\n\t\t\texecutorOrder := make([]string, 0)\n\n\t\t\tjim.On(\"steps\").Return(tt.steps)\n\n\t\t\tif len(tt.steps) > 0 {\n\t\t\t\tjim.On(\"startContainer\").Return(func(_ context.Context) error {\n\t\t\t\t\texecutorOrder = append(executorOrder, \"startContainer\")\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfor i, stepModel := range tt.steps {\n\t\t\t\tsm := &stepMock{}\n\n\t\t\t\tsfm.On(\"newStep\", stepModel, rc).Return(sm, nil)\n\n\t\t\t\tsm.On(\"pre\").Return(func(_ context.Context) error {\n\t\t\t\t\tif tt.preSteps[i] {\n\t\t\t\t\t\texecutorOrder = append(executorOrder, \"pre\"+stepModel.ID)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tsm.On(\"main\").Return(func(_ context.Context) error {\n\t\t\t\t\texecutorOrder = append(executorOrder, \"step\"+stepModel.ID)\n\t\t\t\t\tif tt.hasError {\n\t\t\t\t\t\treturn fmt.Errorf(\"error\")\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tsm.On(\"post\").Return(func(_ context.Context) error {\n\t\t\t\t\tif tt.postSteps[i] {\n\t\t\t\t\t\texecutorOrder = append(executorOrder, \"post\"+stepModel.ID)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tdefer sm.AssertExpectations(t)\n\t\t\t}\n\n\t\t\tif len(tt.steps) > 0 {\n\t\t\t\tjim.On(\"matrix\").Return(map[string]interface{}{})\n\n\t\t\t\tjim.On(\"interpolateOutputs\").Return(func(_ context.Context) error {\n\t\t\t\t\texecutorOrder = append(executorOrder, \"interpolateOutputs\")\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tif contains(\"stopContainer\", tt.executedSteps) {\n\t\t\t\t\tjim.On(\"stopContainer\").Return(func(_ context.Context) error {\n\t\t\t\t\t\texecutorOrder = append(executorOrder, \"stopContainer\")\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tjim.On(\"result\", tt.result)\n\n\t\t\t\tjim.On(\"closeContainer\").Return(func(_ context.Context) error {\n\t\t\t\t\texecutorOrder = append(executorOrder, \"closeContainer\")\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\t\t\t}\n\n\t\t\texecutor := newJobExecutor(jim, sfm, rc)\n\t\t\terr := executor(ctx)\n\t\t\tassert.Nil(t, err)\n\t\t\tassert.Equal(t, tt.executedSteps, executorOrder)\n\n\t\t\tjim.AssertExpectations(t)\n\t\t\tsfm.AssertExpectations(t)\n\n\t\t\tfmt.Println(\"::endgroup::\")\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/local_repository_cache.go",
    "content": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\tgoURL \"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/filecollector\"\n)\n\ntype LocalRepositoryCache struct {\n\tParent            ActionCache\n\tLocalRepositories map[string]string\n\tCacheDirCache     map[string]string\n}\n\nfunc (l *LocalRepositoryCache) Fetch(ctx context.Context, cacheDir, url, ref, token string) (string, error) {\n\tlogger := common.Logger(ctx)\n\tlogger.Debugf(\"LocalRepositoryCache fetch %s with ref %s\", url, ref)\n\tif dest, ok := l.LocalRepositories[fmt.Sprintf(\"%s@%s\", url, ref)]; ok {\n\t\tlogger.Infof(\"LocalRepositoryCache matched %s with ref %s to %s\", url, ref, dest)\n\t\tl.CacheDirCache[fmt.Sprintf(\"%s@%s\", cacheDir, ref)] = dest\n\t\treturn ref, nil\n\t}\n\tif purl, err := goURL.Parse(url); err == nil {\n\t\tif dest, ok := l.LocalRepositories[fmt.Sprintf(\"%s@%s\", strings.TrimPrefix(purl.Path, \"/\"), ref)]; ok {\n\t\t\tlogger.Infof(\"LocalRepositoryCache matched %s with ref %s to %s\", url, ref, dest)\n\t\t\tl.CacheDirCache[fmt.Sprintf(\"%s@%s\", cacheDir, ref)] = dest\n\t\t\treturn ref, nil\n\t\t}\n\t}\n\tlogger.Infof(\"LocalRepositoryCache not matched %s with Ref %s\", url, ref)\n\treturn l.Parent.Fetch(ctx, cacheDir, url, ref, token)\n}\n\nfunc (l *LocalRepositoryCache) GetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error) {\n\tlogger := common.Logger(ctx)\n\t// sha is mapped to ref in fetch if there is a local override\n\tif dest, ok := l.CacheDirCache[fmt.Sprintf(\"%s@%s\", cacheDir, sha)]; ok {\n\t\tlogger.Infof(\"LocalRepositoryCache read cachedir %s with ref %s and subpath '%s' from %s\", cacheDir, sha, includePrefix, dest)\n\t\tsrcPath := filepath.Join(dest, includePrefix)\n\t\tbuf := &bytes.Buffer{}\n\t\ttw := tar.NewWriter(buf)\n\t\tdefer tw.Close()\n\t\tsrcPath = filepath.Clean(srcPath)\n\t\tfi, err := os.Lstat(srcPath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttc := &filecollector.TarCollector{\n\t\t\tTarWriter: tw,\n\t\t}\n\t\tif fi.IsDir() {\n\t\t\tsrcPrefix := srcPath\n\t\t\tif !strings.HasSuffix(srcPrefix, string(filepath.Separator)) {\n\t\t\t\tsrcPrefix += string(filepath.Separator)\n\t\t\t}\n\t\t\tfc := &filecollector.FileCollector{\n\t\t\t\tFs:        &filecollector.DefaultFs{},\n\t\t\t\tSrcPath:   srcPath,\n\t\t\t\tSrcPrefix: srcPrefix,\n\t\t\t\tHandler:   tc,\n\t\t\t}\n\t\t\terr = filepath.Walk(srcPath, fc.CollectFiles(ctx, []string{}))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\tvar f io.ReadCloser\n\t\t\tvar linkname string\n\t\t\tif fi.Mode()&fs.ModeSymlink != 0 {\n\t\t\t\tlinkname, err = os.Readlink(srcPath)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tf, err = os.Open(srcPath)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tdefer f.Close()\n\t\t\t}\n\t\t\terr := tc.WriteFile(fi.Name(), fi, linkname, f)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn io.NopCloser(buf), nil\n\t}\n\tlogger.Infof(\"LocalRepositoryCache not matched cachedir %s with Ref %s and subpath '%s'\", cacheDir, sha, includePrefix)\n\treturn l.Parent.GetTarArchive(ctx, cacheDir, sha, includePrefix)\n}\n"
  },
  {
    "path": "pkg/runner/logger.go",
    "content": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\n\t\"github.com/sirupsen/logrus\"\n\t\"golang.org/x/term\"\n)\n\nconst (\n\t// nocolor = 0\n\tred     = 31\n\tgreen   = 32\n\tyellow  = 33\n\tblue    = 34\n\tmagenta = 35\n\tcyan    = 36\n\tgray    = 37\n)\n\nvar colors []int\nvar nextColor int\nvar mux sync.Mutex\n\nfunc init() {\n\tnextColor = 0\n\tcolors = []int{\n\t\tblue, yellow, green, magenta, red, gray, cyan,\n\t}\n}\n\ntype masksContextKey string\n\nconst masksContextKeyVal = masksContextKey(\"logrus.FieldLogger\")\n\n// Logger returns the appropriate logger for current context\nfunc Masks(ctx context.Context) *[]string {\n\tval := ctx.Value(masksContextKeyVal)\n\tif val != nil {\n\t\tif masks, ok := val.(*[]string); ok {\n\t\t\treturn masks\n\t\t}\n\t}\n\treturn &[]string{}\n}\n\n// WithMasks adds a value to the context for the logger\nfunc WithMasks(ctx context.Context, masks *[]string) context.Context {\n\treturn context.WithValue(ctx, masksContextKeyVal, masks)\n}\n\ntype JobLoggerFactory interface {\n\tWithJobLogger() *logrus.Logger\n}\n\ntype jobLoggerFactoryContextKey string\n\nvar jobLoggerFactoryContextKeyVal = (jobLoggerFactoryContextKey)(\"jobloggerkey\")\n\nfunc WithJobLoggerFactory(ctx context.Context, factory JobLoggerFactory) context.Context {\n\treturn context.WithValue(ctx, jobLoggerFactoryContextKeyVal, factory)\n}\n\n// WithJobLogger attaches a new logger to context that is aware of steps\nfunc WithJobLogger(ctx context.Context, jobID string, jobName string, config *Config, masks *[]string, matrix map[string]interface{}) context.Context {\n\tctx = WithMasks(ctx, masks)\n\n\tvar logger *logrus.Logger\n\tif jobLoggerFactory, ok := ctx.Value(jobLoggerFactoryContextKeyVal).(JobLoggerFactory); ok && jobLoggerFactory != nil {\n\t\tlogger = jobLoggerFactory.WithJobLogger()\n\t} else {\n\t\tvar formatter logrus.Formatter\n\t\tif config.JSONLogger {\n\t\t\tformatter = &logrus.JSONFormatter{}\n\t\t} else {\n\t\t\tmux.Lock()\n\t\t\tdefer mux.Unlock()\n\t\t\tnextColor++\n\t\t\tformatter = &jobLogFormatter{\n\t\t\t\tcolor:          colors[nextColor%len(colors)],\n\t\t\t\tlogPrefixJobID: config.LogPrefixJobID,\n\t\t\t}\n\t\t}\n\n\t\tlogger = logrus.New()\n\t\tlogger.SetOutput(os.Stdout)\n\t\tlogger.SetLevel(logrus.GetLevel())\n\t\tlogger.SetFormatter(formatter)\n\t}\n\n\tlogger.SetFormatter(&maskedFormatter{\n\t\tFormatter: logger.Formatter,\n\t\tmasker:    valueMasker(config.InsecureSecrets, config.Secrets),\n\t})\n\trtn := logger.WithFields(logrus.Fields{\n\t\t\"job\":    jobName,\n\t\t\"jobID\":  jobID,\n\t\t\"dryrun\": common.Dryrun(ctx),\n\t\t\"matrix\": matrix,\n\t}).WithContext(ctx)\n\n\treturn common.WithLogger(ctx, rtn)\n}\n\nfunc WithCompositeLogger(ctx context.Context, masks *[]string) context.Context {\n\tctx = WithMasks(ctx, masks)\n\treturn common.WithLogger(ctx, common.Logger(ctx).WithFields(logrus.Fields{}).WithContext(ctx))\n}\n\nfunc WithCompositeStepLogger(ctx context.Context, stepID string) context.Context {\n\tval := common.Logger(ctx)\n\tstepIDs := make([]string, 0)\n\n\tif logger, ok := val.(*logrus.Entry); ok {\n\t\tif oldStepIDs, ok := logger.Data[\"stepID\"].([]string); ok {\n\t\t\tstepIDs = append(stepIDs, oldStepIDs...)\n\t\t}\n\t}\n\n\tstepIDs = append(stepIDs, stepID)\n\n\treturn common.WithLogger(ctx, common.Logger(ctx).WithFields(logrus.Fields{\n\t\t\"stepID\": stepIDs,\n\t}).WithContext(ctx))\n}\n\nfunc withStepLogger(ctx context.Context, stepID string, stepName string, stageName string) context.Context {\n\trtn := common.Logger(ctx).WithFields(logrus.Fields{\n\t\t\"step\":   stepName,\n\t\t\"stepID\": []string{stepID},\n\t\t\"stage\":  stageName,\n\t})\n\treturn common.WithLogger(ctx, rtn)\n}\n\ntype entryProcessor func(entry *logrus.Entry) *logrus.Entry\n\nfunc valueMasker(insecureSecrets bool, secrets map[string]string) entryProcessor {\n\tssecrets := []string{}\n\tfor _, v := range secrets {\n\t\tssecrets = append(ssecrets, v)\n\t}\n\treturn func(entry *logrus.Entry) *logrus.Entry {\n\t\tif insecureSecrets {\n\t\t\treturn entry\n\t\t}\n\n\t\tmasks := Masks(entry.Context)\n\n\t\tfor _, v := range ssecrets {\n\t\t\tif v != \"\" {\n\t\t\t\tentry.Message = strings.ReplaceAll(entry.Message, v, \"***\")\n\t\t\t}\n\t\t}\n\n\t\tfor _, v := range *masks {\n\t\t\tif v != \"\" {\n\t\t\t\tentry.Message = strings.ReplaceAll(entry.Message, v, \"***\")\n\t\t\t}\n\t\t}\n\n\t\treturn entry\n\t}\n}\n\ntype maskedFormatter struct {\n\tlogrus.Formatter\n\tmasker entryProcessor\n}\n\nfunc (f *maskedFormatter) Format(entry *logrus.Entry) ([]byte, error) {\n\treturn f.Formatter.Format(f.masker(entry))\n}\n\ntype jobLogFormatter struct {\n\tcolor          int\n\tlogPrefixJobID bool\n}\n\nfunc (f *jobLogFormatter) Format(entry *logrus.Entry) ([]byte, error) {\n\tb := &bytes.Buffer{}\n\n\tif f.isColored(entry) {\n\t\tf.printColored(b, entry)\n\t} else {\n\t\tf.print(b, entry)\n\t}\n\n\tb.WriteByte('\\n')\n\treturn b.Bytes(), nil\n}\n\nfunc (f *jobLogFormatter) printColored(b *bytes.Buffer, entry *logrus.Entry) {\n\tentry.Message = strings.TrimSuffix(entry.Message, \"\\n\")\n\n\tvar job any\n\tif f.logPrefixJobID {\n\t\tjob = entry.Data[\"jobID\"]\n\t} else {\n\t\tjob = entry.Data[\"job\"]\n\t}\n\n\tdebugFlag := \"\"\n\tif entry.Level == logrus.DebugLevel {\n\t\tdebugFlag = \"[DEBUG] \"\n\t}\n\n\tif entry.Data[\"raw_output\"] == true {\n\t\tfmt.Fprintf(b, \"\\x1b[%dm|\\x1b[0m %s\", f.color, entry.Message)\n\t} else if entry.Data[\"dryrun\"] == true {\n\t\tfmt.Fprintf(b, \"\\x1b[1m\\x1b[%dm\\x1b[7m*DRYRUN*\\x1b[0m \\x1b[%dm[%s] \\x1b[0m%s%s\", gray, f.color, job, debugFlag, entry.Message)\n\t} else {\n\t\tfmt.Fprintf(b, \"\\x1b[%dm[%s] \\x1b[0m%s%s\", f.color, job, debugFlag, entry.Message)\n\t}\n}\n\nfunc (f *jobLogFormatter) print(b *bytes.Buffer, entry *logrus.Entry) {\n\tentry.Message = strings.TrimSuffix(entry.Message, \"\\n\")\n\n\tvar job any\n\tif f.logPrefixJobID {\n\t\tjob = entry.Data[\"jobID\"]\n\t} else {\n\t\tjob = entry.Data[\"job\"]\n\t}\n\n\tdebugFlag := \"\"\n\tif entry.Level == logrus.DebugLevel {\n\t\tdebugFlag = \"[DEBUG] \"\n\t}\n\n\tif entry.Data[\"raw_output\"] == true {\n\t\tfmt.Fprintf(b, \"[%s]   | %s\", job, entry.Message)\n\t} else if entry.Data[\"dryrun\"] == true {\n\t\tfmt.Fprintf(b, \"*DRYRUN* [%s] %s%s\", job, debugFlag, entry.Message)\n\t} else {\n\t\tfmt.Fprintf(b, \"[%s] %s%s\", job, debugFlag, entry.Message)\n\t}\n}\n\nfunc (f *jobLogFormatter) isColored(entry *logrus.Entry) bool {\n\tisColored := checkIfTerminal(entry.Logger.Out)\n\n\tif force, ok := os.LookupEnv(\"CLICOLOR_FORCE\"); ok && force != \"0\" {\n\t\tisColored = true\n\t} else if ok && force == \"0\" {\n\t\tisColored = false\n\t} else if os.Getenv(\"CLICOLOR\") == \"0\" {\n\t\tisColored = false\n\t}\n\n\treturn isColored\n}\n\nfunc checkIfTerminal(w io.Writer) bool {\n\tswitch v := w.(type) {\n\tcase *os.File:\n\t\treturn term.IsTerminal(int(v.Fd()))\n\tdefault:\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/res/trampoline.js",
    "content": "const { spawnSync } = require('child_process')\nconst spawnArguments = {\n  cwd: process.env.INPUT_CWD,\n  stdio: [\n    process.stdin,\n    process.stdout,\n    process.stderr\n  ]\n}\nconst child = spawnSync(\n  '/bin/sh',\n  ['-c'].concat(process.env.INPUT_COMMAND),\n  spawnArguments)\nprocess.exit(child.status)\n"
  },
  {
    "path": "pkg/runner/reusable_workflow.go",
    "content": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"sync\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/common/git\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nfunc newLocalReusableWorkflowExecutor(rc *RunContext) common.Executor {\n\treturn newReusableWorkflowExecutor(rc, rc.Config.Workdir, rc.Run.Job().Uses)\n}\n\nfunc newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {\n\tuses := rc.Run.Job().Uses\n\n\tremoteReusableWorkflow := newRemoteReusableWorkflow(uses)\n\tif remoteReusableWorkflow == nil {\n\t\treturn common.NewErrorExecutor(fmt.Errorf(\"expected format {owner}/{repo}/.github/workflows/{filename}@{ref}. Actual '%s' Input string was not in a correct format\", uses))\n\t}\n\n\t// uses with safe filename makes the target directory look something like this {owner}-{repo}-.github-workflows-{filename}@{ref}\n\t// instead we will just use {owner}-{repo}@{ref} as our target directory. This should also improve performance when we are using\n\t// multiple reusable workflows from the same repository and ref since for each workflow we won't have to clone it again\n\tfilename := fmt.Sprintf(\"%s/%s@%s\", remoteReusableWorkflow.Org, remoteReusableWorkflow.Repo, remoteReusableWorkflow.Ref)\n\tworkflowDir := fmt.Sprintf(\"%s/%s\", rc.ActionCacheDir(), safeFilename(filename))\n\n\tif rc.Config.ActionCache != nil {\n\t\treturn newActionCacheReusableWorkflowExecutor(rc, filename, remoteReusableWorkflow)\n\t}\n\n\treturn common.NewPipelineExecutor(\n\t\tnewMutexExecutor(cloneIfRequired(rc, *remoteReusableWorkflow, workflowDir)),\n\t\tnewReusableWorkflowExecutor(rc, workflowDir, fmt.Sprintf(\"./.github/workflows/%s\", remoteReusableWorkflow.Filename)),\n\t)\n}\n\nfunc newActionCacheReusableWorkflowExecutor(rc *RunContext, filename string, remoteReusableWorkflow *remoteReusableWorkflow) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tghctx := rc.getGithubContext(ctx)\n\t\tremoteReusableWorkflow.URL = ghctx.ServerURL\n\t\tsha, err := rc.Config.ActionCache.Fetch(ctx, filename, remoteReusableWorkflow.CloneURL(), remoteReusableWorkflow.Ref, ghctx.Token)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tarchive, err := rc.Config.ActionCache.GetTarArchive(ctx, filename, sha, fmt.Sprintf(\".github/workflows/%s\", remoteReusableWorkflow.Filename))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer archive.Close()\n\t\ttreader := tar.NewReader(archive)\n\t\tif _, err = treader.Next(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tplanner, err := model.NewSingleWorkflowPlanner(remoteReusableWorkflow.Filename, treader)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tplan, err := planner.PlanEvent(\"workflow_call\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\trunner, err := NewReusableWorkflowRunner(rc)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn runner.NewPlanExecutor(plan)(ctx)\n\t}\n}\n\nvar (\n\texecutorLock sync.Mutex\n)\n\nfunc newMutexExecutor(executor common.Executor) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\texecutorLock.Lock()\n\t\tdefer executorLock.Unlock()\n\n\t\treturn executor(ctx)\n\t}\n}\n\nfunc cloneIfRequired(rc *RunContext, remoteReusableWorkflow remoteReusableWorkflow, targetDirectory string) common.Executor {\n\treturn common.NewConditionalExecutor(\n\t\tfunc(_ context.Context) bool {\n\t\t\t_, err := os.Stat(targetDirectory)\n\t\t\tnotExists := errors.Is(err, fs.ErrNotExist)\n\t\t\treturn notExists\n\t\t},\n\t\tfunc(ctx context.Context) error {\n\t\t\tremoteReusableWorkflow.URL = rc.getGithubContext(ctx).ServerURL\n\t\t\treturn git.NewGitCloneExecutor(git.NewGitCloneExecutorInput{\n\t\t\t\tURL:         remoteReusableWorkflow.CloneURL(),\n\t\t\t\tRef:         remoteReusableWorkflow.Ref,\n\t\t\t\tDir:         targetDirectory,\n\t\t\t\tToken:       rc.Config.Token,\n\t\t\t\tOfflineMode: rc.Config.ActionOfflineMode,\n\t\t\t})(ctx)\n\t\t},\n\t\tnil,\n\t)\n}\n\nfunc newReusableWorkflowExecutor(rc *RunContext, directory string, workflow string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tplanner, err := model.NewWorkflowPlanner(path.Join(directory, workflow), true, false)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tplan, err := planner.PlanEvent(\"workflow_call\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\trunner, err := NewReusableWorkflowRunner(rc)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn runner.NewPlanExecutor(plan)(ctx)\n\t}\n}\n\nfunc NewReusableWorkflowRunner(rc *RunContext) (Runner, error) {\n\trunner := &runnerImpl{\n\t\tconfig:    rc.Config,\n\t\teventJSON: rc.EventJSON,\n\t\tcaller: &caller{\n\t\t\trunContext: rc,\n\t\t},\n\t}\n\n\treturn runner.configure()\n}\n\ntype remoteReusableWorkflow struct {\n\tURL      string\n\tOrg      string\n\tRepo     string\n\tFilename string\n\tRef      string\n}\n\nfunc (r *remoteReusableWorkflow) CloneURL() string {\n\treturn fmt.Sprintf(\"%s/%s/%s\", r.URL, r.Org, r.Repo)\n}\n\nfunc newRemoteReusableWorkflow(uses string) *remoteReusableWorkflow {\n\t// GitHub docs:\n\t// https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_iduses\n\tr := regexp.MustCompile(`^([^/]+)/([^/]+)/.github/workflows/([^@]+)@(.*)$`)\n\tmatches := r.FindStringSubmatch(uses)\n\tif len(matches) != 5 {\n\t\treturn nil\n\t}\n\treturn &remoteReusableWorkflow{\n\t\tOrg:      matches[1],\n\t\tRepo:     matches[2],\n\t\tFilename: matches[3],\n\t\tRef:      matches[4],\n\t\tURL:      \"https://github.com\",\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/run_context.go",
    "content": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/docker/go-connections/nat\"\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/exprparser\"\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/opencontainers/selinux/go-selinux\"\n)\n\n// RunContext contains info about current job\ntype RunContext struct {\n\tName                string\n\tConfig              *Config\n\tMatrix              map[string]interface{}\n\tRun                 *model.Run\n\tEventJSON           string\n\tEnv                 map[string]string\n\tGlobalEnv           map[string]string // to pass env changes of GITHUB_ENV and set-env correctly, due to dirty Env field\n\tExtraPath           []string\n\tCurrentStep         string\n\tStepResults         map[string]*model.StepResult\n\tIntraActionState    map[string]map[string]string\n\tExprEval            ExpressionEvaluator\n\tJobContainer        container.ExecutionsEnvironment\n\tServiceContainers   []container.ExecutionsEnvironment\n\tOutputMappings      map[MappableOutput]MappableOutput\n\tJobName             string\n\tActionPath          string\n\tParent              *RunContext\n\tMasks               []string\n\tcleanUpJobContainer common.Executor\n\tcaller              *caller // job calling this RunContext (reusable workflows)\n\tCancelled           bool\n\tnodeToolFullPath    string\n}\n\nfunc (rc *RunContext) AddMask(mask string) {\n\trc.Masks = append(rc.Masks, mask)\n}\n\ntype MappableOutput struct {\n\tStepID     string\n\tOutputName string\n}\n\nfunc (rc *RunContext) String() string {\n\tname := fmt.Sprintf(\"%s/%s\", rc.Run.Workflow.Name, rc.Name)\n\tif rc.caller != nil {\n\t\t// prefix the reusable workflow with the caller job\n\t\t// this is required to create unique container names\n\t\tname = fmt.Sprintf(\"%s/%s\", rc.caller.runContext.Name, name)\n\t}\n\treturn name\n}\n\n// GetEnv returns the env for the context\nfunc (rc *RunContext) GetEnv() map[string]string {\n\tif rc.Env == nil {\n\t\trc.Env = map[string]string{}\n\t\tif rc.Run != nil && rc.Run.Workflow != nil && rc.Config != nil {\n\t\t\tjob := rc.Run.Job()\n\t\t\tif job != nil {\n\t\t\t\trc.Env = mergeMaps(rc.Run.Workflow.Env, job.Environment(), rc.Config.Env)\n\t\t\t}\n\t\t}\n\t}\n\trc.Env[\"ACT\"] = \"true\"\n\treturn rc.Env\n}\n\nfunc (rc *RunContext) jobContainerName() string {\n\treturn createContainerName(\"act\", rc.String())\n}\n\n// networkName return the name of the network which will be created by `act` automatically for job,\n// only create network if using a service container\nfunc (rc *RunContext) networkName() (string, bool) {\n\tif len(rc.Run.Job().Services) > 0 {\n\t\treturn fmt.Sprintf(\"%s-%s-network\", rc.jobContainerName(), rc.Run.JobID), true\n\t}\n\tif rc.Config.ContainerNetworkMode == \"\" {\n\t\treturn \"host\", false\n\t}\n\treturn string(rc.Config.ContainerNetworkMode), false\n}\n\nfunc getDockerDaemonSocketMountPath(daemonPath string) string {\n\tif protoIndex := strings.Index(daemonPath, \"://\"); protoIndex != -1 {\n\t\tscheme := daemonPath[:protoIndex]\n\t\tif strings.EqualFold(scheme, \"npipe\") {\n\t\t\t// linux container mount on windows, use the default socket path of the VM / wsl2\n\t\t\treturn \"/var/run/docker.sock\"\n\t\t} else if strings.EqualFold(scheme, \"unix\") {\n\t\t\treturn daemonPath[protoIndex+3:]\n\t\t} else if strings.IndexFunc(scheme, func(r rune) bool {\n\t\t\treturn (r < 'a' || r > 'z') && (r < 'A' || r > 'Z')\n\t\t}) == -1 {\n\t\t\t// unknown protocol use default\n\t\t\treturn \"/var/run/docker.sock\"\n\t\t}\n\t}\n\treturn daemonPath\n}\n\n// Returns the binds and mounts for the container, resolving paths as appropriate\nfunc (rc *RunContext) GetBindsAndMounts() ([]string, map[string]string) {\n\tname := rc.jobContainerName()\n\n\tif rc.Config.ContainerDaemonSocket == \"\" {\n\t\trc.Config.ContainerDaemonSocket = \"/var/run/docker.sock\"\n\t}\n\n\tbinds := []string{}\n\tif rc.Config.ContainerDaemonSocket != \"-\" {\n\t\tdaemonPath := getDockerDaemonSocketMountPath(rc.Config.ContainerDaemonSocket)\n\t\tbinds = append(binds, fmt.Sprintf(\"%s:%s\", daemonPath, \"/var/run/docker.sock\"))\n\t}\n\n\text := container.LinuxContainerEnvironmentExtensions{}\n\n\tif hostEnv, ok := rc.JobContainer.(*container.HostEnvironment); ok {\n\t\tmounts := map[string]string{}\n\t\t// Permission issues?\n\t\t// binds = append(binds, hostEnv.ToolCache+\":/opt/hostedtoolcache\")\n\t\tbinds = append(binds, hostEnv.GetActPath()+\":\"+ext.GetActPath())\n\t\tbinds = append(binds, hostEnv.ToContainerPath(rc.Config.Workdir)+\":\"+ext.ToContainerPath(rc.Config.Workdir))\n\t\treturn binds, mounts\n\t}\n\tmounts := map[string]string{\n\t\t\"act-toolcache\": \"/opt/hostedtoolcache\",\n\t\tname + \"-env\":   ext.GetActPath(),\n\t}\n\n\tif job := rc.Run.Job(); job != nil {\n\t\tif container := job.Container(); container != nil {\n\t\t\tfor _, v := range container.Volumes {\n\t\t\t\tif !strings.Contains(v, \":\") || filepath.IsAbs(v) {\n\t\t\t\t\t// Bind anonymous volume or host file.\n\t\t\t\t\tbinds = append(binds, v)\n\t\t\t\t} else {\n\t\t\t\t\t// Mount existing volume.\n\t\t\t\t\tpaths := strings.SplitN(v, \":\", 2)\n\t\t\t\t\tmounts[paths[0]] = paths[1]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif rc.Config.BindWorkdir {\n\t\tbindModifiers := \"\"\n\t\tif runtime.GOOS == \"darwin\" {\n\t\t\tbindModifiers = \":delegated\"\n\t\t}\n\t\tif selinux.GetEnabled() {\n\t\t\tbindModifiers = \":z\"\n\t\t}\n\t\tbinds = append(binds, fmt.Sprintf(\"%s:%s%s\", rc.Config.Workdir, ext.ToContainerPath(rc.Config.Workdir), bindModifiers))\n\t} else {\n\t\tmounts[name] = ext.ToContainerPath(rc.Config.Workdir)\n\t}\n\n\treturn binds, mounts\n}\n\nfunc (rc *RunContext) startHostEnvironment() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\trawLogger := logger.WithField(\"raw_output\", true)\n\t\tlogWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool {\n\t\t\tif rc.Config.LogOutput {\n\t\t\t\trawLogger.Infof(\"%s\", s)\n\t\t\t} else {\n\t\t\t\trawLogger.Debugf(\"%s\", s)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\tcacheDir := rc.ActionCacheDir()\n\t\trandBytes := make([]byte, 8)\n\t\t_, _ = rand.Read(randBytes)\n\t\tmiscpath := filepath.Join(cacheDir, hex.EncodeToString(randBytes))\n\t\tactPath := filepath.Join(miscpath, \"act\")\n\t\tif err := os.MkdirAll(actPath, 0o777); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tpath := filepath.Join(miscpath, \"hostexecutor\")\n\t\tif err := os.MkdirAll(path, 0o777); err != nil {\n\t\t\treturn err\n\t\t}\n\t\trunnerTmp := filepath.Join(miscpath, \"tmp\")\n\t\tif err := os.MkdirAll(runnerTmp, 0o777); err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttoolCache := filepath.Join(cacheDir, \"tool_cache\")\n\t\trc.JobContainer = &container.HostEnvironment{\n\t\t\tPath:      path,\n\t\t\tTmpDir:    runnerTmp,\n\t\t\tToolCache: toolCache,\n\t\t\tWorkdir:   rc.Config.Workdir,\n\t\t\tActPath:   actPath,\n\t\t\tCleanUp: func() {\n\t\t\t\tos.RemoveAll(miscpath)\n\t\t\t},\n\t\t\tStdOut: logWriter,\n\t\t}\n\t\trc.cleanUpJobContainer = rc.JobContainer.Remove()\n\t\tfor k, v := range rc.JobContainer.GetRunnerContext(ctx) {\n\t\t\tif v, ok := v.(string); ok {\n\t\t\t\trc.Env[fmt.Sprintf(\"RUNNER_%s\", strings.ToUpper(k))] = v\n\t\t\t}\n\t\t}\n\t\tfor _, env := range os.Environ() {\n\t\t\tif k, v, ok := strings.Cut(env, \"=\"); ok {\n\t\t\t\t// don't override\n\t\t\t\tif _, ok := rc.Env[k]; !ok {\n\t\t\t\t\trc.Env[k] = v\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn common.NewPipelineExecutor(\n\t\t\trc.JobContainer.Copy(rc.JobContainer.GetActPath()+\"/\", &container.FileEntry{\n\t\t\t\tName: \"workflow/event.json\",\n\t\t\t\tMode: 0o644,\n\t\t\t\tBody: rc.EventJSON,\n\t\t\t}, &container.FileEntry{\n\t\t\t\tName: \"workflow/envs.txt\",\n\t\t\t\tMode: 0o666,\n\t\t\t\tBody: \"\",\n\t\t\t}),\n\t\t)(ctx)\n\t}\n}\n\nfunc (rc *RunContext) startJobContainer() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\timage := rc.platformImage(ctx)\n\t\trawLogger := logger.WithField(\"raw_output\", true)\n\t\tlogWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool {\n\t\t\tif rc.Config.LogOutput {\n\t\t\t\trawLogger.Infof(\"%s\", s)\n\t\t\t} else {\n\t\t\t\trawLogger.Debugf(\"%s\", s)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\n\t\tusername, password, err := rc.handleCredentials(ctx)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to handle credentials: %s\", err)\n\t\t}\n\n\t\tlogger.Infof(\"\\U0001f680  Start image=%s\", image)\n\t\tname := rc.jobContainerName()\n\n\t\tenvList := make([]string, 0)\n\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_TOOL_CACHE\", \"/opt/hostedtoolcache\"))\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_OS\", \"Linux\"))\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_ARCH\", container.RunnerArch(ctx)))\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_TEMP\", \"/tmp\"))\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"LANG\", \"C.UTF-8\")) // Use same locale as GitHub Actions\n\n\t\text := container.LinuxContainerEnvironmentExtensions{}\n\t\tbinds, mounts := rc.GetBindsAndMounts()\n\n\t\t// specify the network to which the container will connect when `docker create` stage. (like execute command line: docker create --network <networkName> <image>)\n\t\t// if using service containers, will create a new network for the containers.\n\t\t// and it will be removed after at last.\n\t\tnetworkName, createAndDeleteNetwork := rc.networkName()\n\n\t\t// add service containers\n\t\tfor serviceID, spec := range rc.Run.Job().Services {\n\t\t\t// interpolate env\n\t\t\tinterpolatedEnvs := make(map[string]string, len(spec.Env))\n\t\t\tfor k, v := range spec.Env {\n\t\t\t\tinterpolatedEnvs[k] = rc.ExprEval.Interpolate(ctx, v)\n\t\t\t}\n\t\t\tenvs := make([]string, 0, len(interpolatedEnvs))\n\t\t\tfor k, v := range interpolatedEnvs {\n\t\t\t\tenvs = append(envs, fmt.Sprintf(\"%s=%s\", k, v))\n\t\t\t}\n\t\t\tusername, password, err = rc.handleServiceCredentials(ctx, spec.Credentials)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to handle service %s credentials: %w\", serviceID, err)\n\t\t\t}\n\n\t\t\tinterpolatedVolumes := make([]string, 0, len(spec.Volumes))\n\t\t\tfor _, volume := range spec.Volumes {\n\t\t\t\tinterpolatedVolumes = append(interpolatedVolumes, rc.ExprEval.Interpolate(ctx, volume))\n\t\t\t}\n\t\t\tserviceBinds, serviceMounts := rc.GetServiceBindsAndMounts(interpolatedVolumes)\n\n\t\t\tinterpolatedPorts := make([]string, 0, len(spec.Ports))\n\t\t\tfor _, port := range spec.Ports {\n\t\t\t\tinterpolatedPorts = append(interpolatedPorts, rc.ExprEval.Interpolate(ctx, port))\n\t\t\t}\n\t\t\texposedPorts, portBindings, err := nat.ParsePortSpecs(interpolatedPorts)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to parse service %s ports: %w\", serviceID, err)\n\t\t\t}\n\n\t\t\timageName := rc.ExprEval.Interpolate(ctx, spec.Image)\n\t\t\tif imageName == \"\" {\n\t\t\t\tlogger.Infof(\"The service '%s' will not be started because the container definition has an empty image.\", serviceID)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tserviceContainerName := createContainerName(rc.jobContainerName(), serviceID)\n\t\t\tc := container.NewContainer(&container.NewContainerInput{\n\t\t\t\tName:           serviceContainerName,\n\t\t\t\tWorkingDir:     ext.ToContainerPath(rc.Config.Workdir),\n\t\t\t\tImage:          imageName,\n\t\t\t\tUsername:       username,\n\t\t\t\tPassword:       password,\n\t\t\t\tEnv:            envs,\n\t\t\t\tMounts:         serviceMounts,\n\t\t\t\tBinds:          serviceBinds,\n\t\t\t\tStdout:         logWriter,\n\t\t\t\tStderr:         logWriter,\n\t\t\t\tPrivileged:     rc.Config.Privileged,\n\t\t\t\tUsernsMode:     rc.Config.UsernsMode,\n\t\t\t\tPlatform:       rc.Config.ContainerArchitecture,\n\t\t\t\tOptions:        rc.ExprEval.Interpolate(ctx, spec.Options),\n\t\t\t\tNetworkMode:    networkName,\n\t\t\t\tNetworkAliases: []string{serviceID},\n\t\t\t\tExposedPorts:   exposedPorts,\n\t\t\t\tPortBindings:   portBindings,\n\t\t\t})\n\t\t\trc.ServiceContainers = append(rc.ServiceContainers, c)\n\t\t}\n\n\t\trc.cleanUpJobContainer = func(ctx context.Context) error {\n\t\t\treuseJobContainer := func(_ context.Context) bool {\n\t\t\t\treturn rc.Config.ReuseContainers\n\t\t\t}\n\n\t\t\tif rc.JobContainer != nil {\n\t\t\t\treturn rc.JobContainer.Remove().IfNot(reuseJobContainer).\n\t\t\t\t\tThen(container.NewDockerVolumeRemoveExecutor(rc.jobContainerName(), false)).IfNot(reuseJobContainer).\n\t\t\t\t\tThen(container.NewDockerVolumeRemoveExecutor(rc.jobContainerName()+\"-env\", false)).IfNot(reuseJobContainer).\n\t\t\t\t\tThen(func(ctx context.Context) error {\n\t\t\t\t\t\tif len(rc.ServiceContainers) > 0 {\n\t\t\t\t\t\t\tlogger.Infof(\"Cleaning up services for job %s\", rc.JobName)\n\t\t\t\t\t\t\tif err := rc.stopServiceContainers()(ctx); err != nil {\n\t\t\t\t\t\t\t\tlogger.Errorf(\"Error while cleaning services: %v\", err)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif createAndDeleteNetwork {\n\t\t\t\t\t\t\t\t// clean network if it has been created by act\n\t\t\t\t\t\t\t\t// if using service containers\n\t\t\t\t\t\t\t\t// it means that the network to which containers are connecting is created by `act_runner`,\n\t\t\t\t\t\t\t\t// so, we should remove the network at last.\n\t\t\t\t\t\t\t\tlogger.Infof(\"Cleaning up network for job %s, and network name is: %s\", rc.JobName, networkName)\n\t\t\t\t\t\t\t\tif err := container.NewDockerNetworkRemoveExecutor(networkName)(ctx); err != nil {\n\t\t\t\t\t\t\t\t\tlogger.Errorf(\"Error while cleaning network: %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t})(ctx)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tjobContainerNetwork := rc.Config.ContainerNetworkMode.NetworkName()\n\t\tif rc.containerImage(ctx) != \"\" {\n\t\t\tjobContainerNetwork = networkName\n\t\t} else if jobContainerNetwork == \"\" {\n\t\t\tjobContainerNetwork = \"host\"\n\t\t}\n\n\t\trc.JobContainer = container.NewContainer(&container.NewContainerInput{\n\t\t\tCmd:            nil,\n\t\t\tEntrypoint:     []string{\"tail\", \"-f\", \"/dev/null\"},\n\t\t\tWorkingDir:     ext.ToContainerPath(rc.Config.Workdir),\n\t\t\tImage:          image,\n\t\t\tUsername:       username,\n\t\t\tPassword:       password,\n\t\t\tName:           name,\n\t\t\tEnv:            envList,\n\t\t\tMounts:         mounts,\n\t\t\tNetworkMode:    jobContainerNetwork,\n\t\t\tNetworkAliases: []string{rc.Name},\n\t\t\tBinds:          binds,\n\t\t\tStdout:         logWriter,\n\t\t\tStderr:         logWriter,\n\t\t\tPrivileged:     rc.Config.Privileged,\n\t\t\tUsernsMode:     rc.Config.UsernsMode,\n\t\t\tPlatform:       rc.Config.ContainerArchitecture,\n\t\t\tOptions:        rc.options(ctx),\n\t\t})\n\t\tif rc.JobContainer == nil {\n\t\t\treturn errors.New(\"Failed to create job container\")\n\t\t}\n\n\t\treturn common.NewPipelineExecutor(\n\t\t\trc.pullServicesImages(rc.Config.ForcePull),\n\t\t\trc.JobContainer.Pull(rc.Config.ForcePull),\n\t\t\trc.stopJobContainer(),\n\t\t\tcontainer.NewDockerNetworkCreateExecutor(networkName).IfBool(createAndDeleteNetwork),\n\t\t\trc.startServiceContainers(networkName),\n\t\t\trc.JobContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),\n\t\t\trc.JobContainer.Start(false),\n\t\t\trc.JobContainer.Copy(rc.JobContainer.GetActPath()+\"/\", &container.FileEntry{\n\t\t\t\tName: \"workflow/event.json\",\n\t\t\t\tMode: 0o644,\n\t\t\t\tBody: rc.EventJSON,\n\t\t\t}, &container.FileEntry{\n\t\t\t\tName: \"workflow/envs.txt\",\n\t\t\t\tMode: 0o666,\n\t\t\t\tBody: \"\",\n\t\t\t}),\n\t\t\trc.waitForServiceContainers(),\n\t\t)(ctx)\n\t}\n}\n\nfunc (rc *RunContext) execJobContainer(cmd []string, env map[string]string, user, workdir string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\treturn rc.JobContainer.Exec(cmd, env, user, workdir)(ctx)\n\t}\n}\n\nfunc (rc *RunContext) InitializeNodeTool() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tctx, cancel := common.EarlyCancelContext(ctx)\n\t\tdefer cancel()\n\t\trc.GetNodeToolFullPath(ctx)\n\t\treturn nil\n\t}\n}\n\nfunc (rc *RunContext) GetNodeToolFullPath(ctx context.Context) string {\n\tif rc.nodeToolFullPath == \"\" {\n\t\ttimeed, cancel := context.WithTimeout(ctx, time.Minute)\n\t\tdefer cancel()\n\t\tpath := rc.JobContainer.GetPathVariableName()\n\t\tcenv := map[string]string{}\n\t\tvar cpath string\n\t\tif err := rc.JobContainer.UpdateFromImageEnv(&cenv)(ctx); err == nil {\n\t\t\tif p, ok := cenv[path]; ok {\n\t\t\t\tcpath = p\n\t\t\t}\n\t\t}\n\t\tif len(cpath) == 0 {\n\t\t\tcpath = rc.JobContainer.DefaultPathVariable()\n\t\t}\n\t\tcenv[path] = cpath\n\t\thout := &bytes.Buffer{}\n\t\therr := &bytes.Buffer{}\n\t\tstdout, stderr := rc.JobContainer.ReplaceLogWriter(hout, herr)\n\t\terr := rc.execJobContainer([]string{\"node\", \"--no-warnings\", \"-e\", \"console.log(process.execPath)\"},\n\t\t\tcenv, \"\", \"\").\n\t\t\tFinally(func(context.Context) error {\n\t\t\t\trc.JobContainer.ReplaceLogWriter(stdout, stderr)\n\t\t\t\treturn nil\n\t\t\t})(timeed)\n\t\trawStr := strings.Trim(hout.String(), \"\\r\\n\")\n\t\tif err == nil && !strings.ContainsAny(rawStr, \"\\r\\n\") {\n\t\t\trc.nodeToolFullPath = rawStr\n\t\t} else {\n\t\t\trc.nodeToolFullPath = \"node\"\n\t\t}\n\t}\n\treturn rc.nodeToolFullPath\n}\n\nfunc (rc *RunContext) ApplyExtraPath(ctx context.Context, env *map[string]string) {\n\tif len(rc.ExtraPath) > 0 {\n\t\tpath := rc.JobContainer.GetPathVariableName()\n\t\tif rc.JobContainer.IsEnvironmentCaseInsensitive() {\n\t\t\t// On windows system Path and PATH could also be in the map\n\t\t\tfor k := range *env {\n\t\t\t\tif strings.EqualFold(path, k) {\n\t\t\t\t\tpath = k\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (*env)[path] == \"\" {\n\t\t\tcenv := map[string]string{}\n\t\t\tvar cpath string\n\t\t\tif err := rc.JobContainer.UpdateFromImageEnv(&cenv)(ctx); err == nil {\n\t\t\t\tif p, ok := cenv[path]; ok {\n\t\t\t\t\tcpath = p\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(cpath) == 0 {\n\t\t\t\tcpath = rc.JobContainer.DefaultPathVariable()\n\t\t\t}\n\t\t\t(*env)[path] = cpath\n\t\t}\n\t\t(*env)[path] = rc.JobContainer.JoinPathVariable(append(rc.ExtraPath, (*env)[path])...)\n\t}\n}\n\nfunc (rc *RunContext) UpdateExtraPath(ctx context.Context, githubEnvPath string) error {\n\tif common.Dryrun(ctx) {\n\t\treturn nil\n\t}\n\tpathTar, err := rc.JobContainer.GetContainerArchive(ctx, githubEnvPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer pathTar.Close()\n\n\treader := tar.NewReader(pathTar)\n\t_, err = reader.Next()\n\tif err != nil && err != io.EOF {\n\t\treturn err\n\t}\n\ts := bufio.NewScanner(reader)\n\ts.Buffer(nil, 1024*1024*1024) // increase buffer to 1GB to avoid scanner buffer overflow\n\tfirstLine := true\n\tfor s.Scan() {\n\t\tline := s.Text()\n\t\tif firstLine {\n\t\t\tfirstLine = false\n\t\t\t// skip utf8 bom, powershell 5 legacy uses it for utf8\n\t\t\tif len(line) >= 3 && line[0] == 239 && line[1] == 187 && line[2] == 191 {\n\t\t\t\tline = line[3:]\n\t\t\t}\n\t\t}\n\t\tif len(line) > 0 {\n\t\t\trc.addPath(ctx, line)\n\t\t}\n\t}\n\treturn s.Err()\n}\n\n// stopJobContainer removes the job container (if it exists) and its volume (if it exists)\nfunc (rc *RunContext) stopJobContainer() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tif rc.cleanUpJobContainer != nil {\n\t\t\treturn rc.cleanUpJobContainer(ctx)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (rc *RunContext) pullServicesImages(forcePull bool) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\texecs := []common.Executor{}\n\t\tfor _, c := range rc.ServiceContainers {\n\t\t\texecs = append(execs, c.Pull(forcePull))\n\t\t}\n\t\treturn common.NewParallelExecutor(len(execs), execs...)(ctx)\n\t}\n}\n\nfunc (rc *RunContext) startServiceContainers(_ string) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\texecs := []common.Executor{}\n\t\tfor _, c := range rc.ServiceContainers {\n\t\t\texecs = append(execs, common.NewPipelineExecutor(\n\t\t\t\tc.Pull(false),\n\t\t\t\tc.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),\n\t\t\t\tc.Start(false),\n\t\t\t))\n\t\t}\n\t\treturn common.NewParallelExecutor(len(execs), execs...)(ctx)\n\t}\n}\n\nfunc (rc *RunContext) waitForServiceContainer(c container.ExecutionsEnvironment) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tsctx, cancel := context.WithTimeout(ctx, time.Minute*5)\n\t\tdefer cancel()\n\t\thealth := container.HealthStarting\n\t\tdelay := time.Second\n\t\tfor i := 0; ; i++ {\n\t\t\thealth = c.GetHealth(sctx)\n\t\t\tif health != container.HealthStarting || i > 30 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ttime.Sleep(delay)\n\t\t\tdelay *= 2\n\t\t\tif delay > 10*time.Second {\n\t\t\t\tdelay = 10 * time.Second\n\t\t\t}\n\t\t}\n\t\tif health == container.HealthHealthy {\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"service container failed to start\")\n\t}\n}\n\nfunc (rc *RunContext) waitForServiceContainers() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\texecs := []common.Executor{}\n\t\tfor _, c := range rc.ServiceContainers {\n\t\t\texecs = append(execs, rc.waitForServiceContainer(c))\n\t\t}\n\t\treturn common.NewParallelExecutor(len(execs), execs...)(ctx)\n\t}\n}\n\nfunc (rc *RunContext) stopServiceContainers() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\texecs := []common.Executor{}\n\t\tfor _, c := range rc.ServiceContainers {\n\t\t\texecs = append(execs, c.Remove().Finally(c.Close()))\n\t\t}\n\t\treturn common.NewParallelExecutor(len(execs), execs...)(ctx)\n\t}\n}\n\n// Prepare the mounts and binds for the worker\n\n// ActionCacheDir is for rc\nfunc (rc *RunContext) ActionCacheDir() string {\n\tif rc.Config.ActionCacheDir != \"\" {\n\t\treturn rc.Config.ActionCacheDir\n\t}\n\tvar xdgCache string\n\tvar ok bool\n\tif xdgCache, ok = os.LookupEnv(\"XDG_CACHE_HOME\"); !ok || xdgCache == \"\" {\n\t\tif home, err := os.UserHomeDir(); err == nil {\n\t\t\txdgCache = filepath.Join(home, \".cache\")\n\t\t} else if xdgCache, err = filepath.Abs(\".\"); err != nil {\n\t\t\t// It's almost impossible to get here, so the temp dir is a good fallback\n\t\t\txdgCache = os.TempDir()\n\t\t}\n\t}\n\treturn filepath.Join(xdgCache, \"act\")\n}\n\n// Interpolate outputs after a job is done\nfunc (rc *RunContext) interpolateOutputs() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tee := rc.NewExpressionEvaluator(ctx)\n\t\tfor k, v := range rc.Run.Job().Outputs {\n\t\t\tinterpolated := ee.Interpolate(ctx, v)\n\t\t\tif v != interpolated {\n\t\t\t\trc.Run.Job().Outputs[k] = interpolated\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (rc *RunContext) startContainer() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tctx, cancel := common.EarlyCancelContext(ctx)\n\t\tdefer cancel()\n\t\tif rc.IsHostEnv(ctx) {\n\t\t\treturn rc.startHostEnvironment()(ctx)\n\t\t}\n\t\treturn rc.startJobContainer()(ctx)\n\t}\n}\n\nfunc (rc *RunContext) IsHostEnv(ctx context.Context) bool {\n\tplatform := rc.runsOnImage(ctx)\n\timage := rc.containerImage(ctx)\n\treturn image == \"\" && strings.EqualFold(platform, \"-self-hosted\")\n}\n\nfunc (rc *RunContext) stopContainer() common.Executor {\n\treturn rc.stopJobContainer()\n}\n\nfunc (rc *RunContext) closeContainer() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tif rc.JobContainer != nil {\n\t\t\treturn rc.JobContainer.Close()(ctx)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (rc *RunContext) matrix() map[string]interface{} {\n\treturn rc.Matrix\n}\n\nfunc (rc *RunContext) result(result string) {\n\trc.Run.Job().Result = result\n}\n\nfunc (rc *RunContext) steps() []*model.Step {\n\treturn rc.Run.Job().Steps\n}\n\n// Executor returns a pipeline executor for all the steps in the job\nfunc (rc *RunContext) Executor() (common.Executor, error) {\n\tvar executor common.Executor\n\tvar jobType, err = rc.Run.Job().Type()\n\n\tswitch jobType {\n\tcase model.JobTypeDefault:\n\t\texecutor = newJobExecutor(rc, &stepFactoryImpl{}, rc)\n\tcase model.JobTypeReusableWorkflowLocal:\n\t\texecutor = newLocalReusableWorkflowExecutor(rc)\n\tcase model.JobTypeReusableWorkflowRemote:\n\t\texecutor = newRemoteReusableWorkflowExecutor(rc)\n\tcase model.JobTypeInvalid:\n\t\treturn nil, err\n\t}\n\n\treturn func(ctx context.Context) error {\n\t\tres, err := rc.isEnabled(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif res {\n\t\t\treturn executor(ctx)\n\t\t}\n\t\treturn nil\n\t}, nil\n}\n\nfunc (rc *RunContext) containerImage(ctx context.Context) string {\n\tjob := rc.Run.Job()\n\n\tc := job.Container()\n\tif c != nil {\n\t\treturn rc.ExprEval.Interpolate(ctx, c.Image)\n\t}\n\n\treturn \"\"\n}\n\nfunc (rc *RunContext) runsOnImage(ctx context.Context) string {\n\tif rc.Run.Job().RunsOn() == nil {\n\t\tcommon.Logger(ctx).Errorf(\"'runs-on' key not defined in %s\", rc.String())\n\t}\n\n\tfor _, platformName := range rc.runsOnPlatformNames(ctx) {\n\t\timage := rc.Config.Platforms[strings.ToLower(platformName)]\n\t\tif image != \"\" {\n\t\t\treturn image\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\nfunc (rc *RunContext) runsOnPlatformNames(ctx context.Context) []string {\n\tjob := rc.Run.Job()\n\n\tif job.RunsOn() == nil {\n\t\treturn []string{}\n\t}\n\n\tif err := rc.ExprEval.EvaluateYamlNode(ctx, &job.RawRunsOn); err != nil {\n\t\tcommon.Logger(ctx).Errorf(\"Error while evaluating runs-on: %v\", err)\n\t\treturn []string{}\n\t}\n\n\treturn job.RunsOn()\n}\n\nfunc (rc *RunContext) platformImage(ctx context.Context) string {\n\tif containerImage := rc.containerImage(ctx); containerImage != \"\" {\n\t\treturn containerImage\n\t}\n\n\treturn rc.runsOnImage(ctx)\n}\n\nfunc (rc *RunContext) options(ctx context.Context) string {\n\tjob := rc.Run.Job()\n\tc := job.Container()\n\tif c != nil {\n\t\treturn rc.ExprEval.Interpolate(ctx, c.Options)\n\t}\n\n\treturn rc.Config.ContainerOptions\n}\n\nfunc (rc *RunContext) isEnabled(ctx context.Context) (bool, error) {\n\tjob := rc.Run.Job()\n\tl := common.Logger(ctx)\n\trunJob, runJobErr := EvalBool(ctx, rc.ExprEval, job.If.Value, exprparser.DefaultStatusCheckSuccess)\n\tjobType, jobTypeErr := job.Type()\n\n\tif runJobErr != nil {\n\t\treturn false, fmt.Errorf(\"  \\u274C  Error in if-expression: \\\"if: %s\\\" (%s)\", job.If.Value, runJobErr)\n\t}\n\n\tif jobType == model.JobTypeInvalid {\n\t\treturn false, jobTypeErr\n\t}\n\n\tif !runJob {\n\t\trc.result(\"skipped\")\n\t\tl.WithField(\"jobResult\", \"skipped\").Debugf(\"Skipping job '%s' due to '%s'\", job.Name, job.If.Value)\n\t\treturn false, nil\n\t}\n\n\tif jobType != model.JobTypeDefault {\n\t\treturn true, nil\n\t}\n\n\timg := rc.platformImage(ctx)\n\tif img == \"\" {\n\t\tfor _, platformName := range rc.runsOnPlatformNames(ctx) {\n\t\t\tl.Infof(\"\\U0001F6A7  Skipping unsupported platform -- Try running with `-P %+v=...`\", platformName)\n\t\t}\n\t\treturn false, nil\n\t}\n\treturn true, nil\n}\n\nfunc mergeMaps(maps ...map[string]string) map[string]string {\n\trtnMap := make(map[string]string)\n\tfor _, m := range maps {\n\t\tfor k, v := range m {\n\t\t\trtnMap[k] = v\n\t\t}\n\t}\n\treturn rtnMap\n}\n\nfunc createContainerName(parts ...string) string {\n\tname := strings.Join(parts, \"-\")\n\tpattern := regexp.MustCompile(\"[^a-zA-Z0-9]\")\n\tname = pattern.ReplaceAllString(name, \"-\")\n\tname = strings.ReplaceAll(name, \"--\", \"-\")\n\thash := sha256.Sum256([]byte(name))\n\n\t// SHA256 is 64 hex characters. So trim name to 63 characters to make room for the hash and separator\n\ttrimmedName := strings.Trim(trimToLen(name, 63), \"-\")\n\n\treturn fmt.Sprintf(\"%s-%x\", trimmedName, hash)\n}\n\nfunc trimToLen(s string, l int) string {\n\tif l < 0 {\n\t\tl = 0\n\t}\n\tif len(s) > l {\n\t\treturn s[:l]\n\t}\n\treturn s\n}\n\nfunc (rc *RunContext) getJobContext() *model.JobContext {\n\tjobStatus := \"success\"\n\tif rc.Cancelled {\n\t\tjobStatus = \"cancelled\"\n\t} else {\n\t\tfor _, stepStatus := range rc.StepResults {\n\t\t\tif stepStatus.Conclusion == model.StepStatusFailure {\n\t\t\t\tjobStatus = \"failure\"\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn &model.JobContext{\n\t\tStatus: jobStatus,\n\t}\n}\n\nfunc (rc *RunContext) getStepsContext() map[string]*model.StepResult {\n\treturn rc.StepResults\n}\n\nfunc (rc *RunContext) getGithubContext(ctx context.Context) *model.GithubContext {\n\tlogger := common.Logger(ctx)\n\tghc := &model.GithubContext{\n\t\tEvent:            make(map[string]interface{}),\n\t\tWorkflow:         rc.Run.Workflow.Name,\n\t\tRunAttempt:       rc.Config.Env[\"GITHUB_RUN_ATTEMPT\"],\n\t\tRunID:            rc.Config.Env[\"GITHUB_RUN_ID\"],\n\t\tRunNumber:        rc.Config.Env[\"GITHUB_RUN_NUMBER\"],\n\t\tActor:            rc.Config.Actor,\n\t\tEventName:        rc.Config.EventName,\n\t\tAction:           rc.CurrentStep,\n\t\tToken:            rc.Config.Token,\n\t\tJob:              rc.Run.JobID,\n\t\tActionPath:       rc.ActionPath,\n\t\tActionRepository: rc.Env[\"GITHUB_ACTION_REPOSITORY\"],\n\t\tActionRef:        rc.Env[\"GITHUB_ACTION_REF\"],\n\t\tRepositoryOwner:  rc.Config.Env[\"GITHUB_REPOSITORY_OWNER\"],\n\t\tRetentionDays:    rc.Config.Env[\"GITHUB_RETENTION_DAYS\"],\n\t\tRunnerPerflog:    rc.Config.Env[\"RUNNER_PERFLOG\"],\n\t\tRunnerTrackingID: rc.Config.Env[\"RUNNER_TRACKING_ID\"],\n\t\tRepository:       rc.Config.Env[\"GITHUB_REPOSITORY\"],\n\t\tRef:              rc.Config.Env[\"GITHUB_REF\"],\n\t\tSha:              rc.Config.Env[\"SHA_REF\"],\n\t\tRefName:          rc.Config.Env[\"GITHUB_REF_NAME\"],\n\t\tRefType:          rc.Config.Env[\"GITHUB_REF_TYPE\"],\n\t\tBaseRef:          rc.Config.Env[\"GITHUB_BASE_REF\"],\n\t\tHeadRef:          rc.Config.Env[\"GITHUB_HEAD_REF\"],\n\t\tWorkspace:        rc.Config.Env[\"GITHUB_WORKSPACE\"],\n\t}\n\tif rc.JobContainer != nil {\n\t\tghc.EventPath = rc.JobContainer.GetActPath() + \"/workflow/event.json\"\n\t\tghc.Workspace = rc.JobContainer.ToContainerPath(rc.Config.Workdir)\n\t}\n\n\tif ghc.RunAttempt == \"\" {\n\t\tghc.RunAttempt = \"1\"\n\t}\n\n\tif ghc.RunID == \"\" {\n\t\tghc.RunID = \"1\"\n\t}\n\n\tif ghc.RunNumber == \"\" {\n\t\tghc.RunNumber = \"1\"\n\t}\n\n\tif ghc.RetentionDays == \"\" {\n\t\tghc.RetentionDays = \"0\"\n\t}\n\n\tif ghc.RunnerPerflog == \"\" {\n\t\tghc.RunnerPerflog = \"/dev/null\"\n\t}\n\n\t// Backwards compatibility for configs that require\n\t// a default rather than being run as a cmd\n\tif ghc.Actor == \"\" {\n\t\tghc.Actor = \"nektos/act\"\n\t}\n\n\tif rc.EventJSON != \"\" {\n\t\terr := json.Unmarshal([]byte(rc.EventJSON), &ghc.Event)\n\t\tif err != nil {\n\t\t\tlogger.Errorf(\"Unable to Unmarshal event '%s': %v\", rc.EventJSON, err)\n\t\t}\n\t}\n\n\tghc.SetBaseAndHeadRef()\n\trepoPath := rc.Config.Workdir\n\tghc.SetRepositoryAndOwner(ctx, rc.Config.GitHubInstance, rc.Config.RemoteName, repoPath)\n\tif ghc.Ref == \"\" {\n\t\tghc.SetRef(ctx, rc.Config.DefaultBranch, repoPath)\n\t}\n\tif ghc.Sha == \"\" {\n\t\tghc.SetSha(ctx, repoPath)\n\t}\n\n\tghc.SetRefTypeAndName()\n\n\t// defaults\n\tghc.ServerURL = \"https://github.com\"\n\tghc.APIURL = \"https://api.github.com\"\n\tghc.GraphQLURL = \"https://api.github.com/graphql\"\n\t// per GHES\n\tif rc.Config.GitHubInstance != \"github.com\" {\n\t\tghc.ServerURL = fmt.Sprintf(\"https://%s\", rc.Config.GitHubInstance)\n\t\tghc.APIURL = fmt.Sprintf(\"https://%s/api/v3\", rc.Config.GitHubInstance)\n\t\tghc.GraphQLURL = fmt.Sprintf(\"https://%s/api/graphql\", rc.Config.GitHubInstance)\n\t}\n\t// allow to be overridden by user\n\tif rc.Config.Env[\"GITHUB_SERVER_URL\"] != \"\" {\n\t\tghc.ServerURL = rc.Config.Env[\"GITHUB_SERVER_URL\"]\n\t}\n\tif rc.Config.Env[\"GITHUB_API_URL\"] != \"\" {\n\t\tghc.APIURL = rc.Config.Env[\"GITHUB_API_URL\"]\n\t}\n\tif rc.Config.Env[\"GITHUB_GRAPHQL_URL\"] != \"\" {\n\t\tghc.GraphQLURL = rc.Config.Env[\"GITHUB_GRAPHQL_URL\"]\n\t}\n\n\treturn ghc\n}\n\nfunc isLocalCheckout(ghc *model.GithubContext, step *model.Step) bool {\n\tif step.Type() == model.StepTypeInvalid {\n\t\t// This will be errored out by the executor later, we need this here to avoid a null panic though\n\t\treturn false\n\t}\n\tif step.Type() != model.StepTypeUsesActionRemote {\n\t\treturn false\n\t}\n\tremoteAction := newRemoteAction(step.Uses)\n\tif remoteAction == nil {\n\t\t// IsCheckout() will nil panic if we dont bail out early\n\t\treturn false\n\t}\n\tif !remoteAction.IsCheckout() {\n\t\treturn false\n\t}\n\n\tif repository, ok := step.With[\"repository\"]; ok && repository != ghc.Repository {\n\t\treturn false\n\t}\n\tif repository, ok := step.With[\"ref\"]; ok && repository != ghc.Ref {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc nestedMapLookup(m map[string]interface{}, ks ...string) (rval interface{}) {\n\tvar ok bool\n\n\tif len(ks) == 0 { // degenerate input\n\t\treturn nil\n\t}\n\tif rval, ok = m[ks[0]]; !ok {\n\t\treturn nil\n\t} else if len(ks) == 1 { // we've reached the final key\n\t\treturn rval\n\t} else if m, ok = rval.(map[string]interface{}); !ok {\n\t\treturn nil\n\t}\n\t// 1+ more keys\n\treturn nestedMapLookup(m, ks[1:]...)\n}\n\nfunc (rc *RunContext) withGithubEnv(ctx context.Context, github *model.GithubContext, env map[string]string) map[string]string {\n\tenv[\"CI\"] = \"true\"\n\tenv[\"GITHUB_WORKFLOW\"] = github.Workflow\n\tenv[\"GITHUB_RUN_ATTEMPT\"] = github.RunAttempt\n\tenv[\"GITHUB_RUN_ID\"] = github.RunID\n\tenv[\"GITHUB_RUN_NUMBER\"] = github.RunNumber\n\tenv[\"GITHUB_ACTION\"] = github.Action\n\tenv[\"GITHUB_ACTION_PATH\"] = github.ActionPath\n\tenv[\"GITHUB_ACTION_REPOSITORY\"] = github.ActionRepository\n\tenv[\"GITHUB_ACTION_REF\"] = github.ActionRef\n\tenv[\"GITHUB_ACTIONS\"] = \"true\"\n\tenv[\"GITHUB_ACTOR\"] = github.Actor\n\tenv[\"GITHUB_REPOSITORY\"] = github.Repository\n\tenv[\"GITHUB_EVENT_NAME\"] = github.EventName\n\tenv[\"GITHUB_EVENT_PATH\"] = github.EventPath\n\tenv[\"GITHUB_WORKSPACE\"] = github.Workspace\n\tenv[\"GITHUB_SHA\"] = github.Sha\n\tenv[\"GITHUB_REF\"] = github.Ref\n\tenv[\"GITHUB_REF_NAME\"] = github.RefName\n\tenv[\"GITHUB_REF_TYPE\"] = github.RefType\n\tenv[\"GITHUB_JOB\"] = github.Job\n\tenv[\"GITHUB_REPOSITORY_OWNER\"] = github.RepositoryOwner\n\tenv[\"GITHUB_RETENTION_DAYS\"] = github.RetentionDays\n\tenv[\"RUNNER_PERFLOG\"] = github.RunnerPerflog\n\tenv[\"RUNNER_TRACKING_ID\"] = github.RunnerTrackingID\n\tenv[\"GITHUB_BASE_REF\"] = github.BaseRef\n\tenv[\"GITHUB_HEAD_REF\"] = github.HeadRef\n\tenv[\"GITHUB_SERVER_URL\"] = github.ServerURL\n\tenv[\"GITHUB_API_URL\"] = github.APIURL\n\tenv[\"GITHUB_GRAPHQL_URL\"] = github.GraphQLURL\n\n\tif rc.Config.ArtifactServerPath != \"\" {\n\t\tsetActionRuntimeVars(rc, env)\n\t}\n\n\tfor _, platformName := range rc.runsOnPlatformNames(ctx) {\n\t\tif platformName != \"\" {\n\t\t\tif platformName == \"ubuntu-latest\" {\n\t\t\t\t// hardcode current ubuntu-latest since we have no way to check that 'on the fly'\n\t\t\t\tenv[\"ImageOS\"] = \"ubuntu20\"\n\t\t\t} else {\n\t\t\t\tplatformName = strings.SplitN(strings.Replace(platformName, `-`, ``, 1), `.`, 2)[0]\n\t\t\t\tenv[\"ImageOS\"] = platformName\n\t\t\t}\n\t\t}\n\t}\n\n\treturn env\n}\n\nfunc setActionRuntimeVars(rc *RunContext, env map[string]string) {\n\tactionsRuntimeURL := os.Getenv(\"ACTIONS_RUNTIME_URL\")\n\tif actionsRuntimeURL == \"\" {\n\t\tactionsRuntimeURL = fmt.Sprintf(\"http://%s:%s/\", rc.Config.ArtifactServerAddr, rc.Config.ArtifactServerPort)\n\t}\n\tenv[\"ACTIONS_RUNTIME_URL\"] = actionsRuntimeURL\n\tenv[\"ACTIONS_RESULTS_URL\"] = actionsRuntimeURL\n\n\tactionsRuntimeToken := os.Getenv(\"ACTIONS_RUNTIME_TOKEN\")\n\tif actionsRuntimeToken == \"\" {\n\t\trunID := int64(1)\n\t\tif rid, ok := rc.Config.Env[\"GITHUB_RUN_ID\"]; ok {\n\t\t\trunID, _ = strconv.ParseInt(rid, 10, 64)\n\t\t}\n\t\tactionsRuntimeToken, _ = common.CreateAuthorizationToken(runID, runID, runID)\n\t}\n\tenv[\"ACTIONS_RUNTIME_TOKEN\"] = actionsRuntimeToken\n}\n\nfunc (rc *RunContext) handleCredentials(ctx context.Context) (string, string, error) {\n\t// TODO: remove below 2 lines when we can release act with breaking changes\n\tusername := rc.Config.Secrets[\"DOCKER_USERNAME\"]\n\tpassword := rc.Config.Secrets[\"DOCKER_PASSWORD\"]\n\n\tcontainer := rc.Run.Job().Container()\n\tif container == nil || container.Credentials == nil {\n\t\treturn username, password, nil\n\t}\n\n\tif container.Credentials != nil && len(container.Credentials) != 2 {\n\t\terr := fmt.Errorf(\"invalid property count for key 'credentials:'\")\n\t\treturn \"\", \"\", err\n\t}\n\n\tee := rc.NewExpressionEvaluator(ctx)\n\tif username = ee.Interpolate(ctx, container.Credentials[\"username\"]); username == \"\" {\n\t\terr := fmt.Errorf(\"failed to interpolate container.credentials.username\")\n\t\treturn \"\", \"\", err\n\t}\n\tif password = ee.Interpolate(ctx, container.Credentials[\"password\"]); password == \"\" {\n\t\terr := fmt.Errorf(\"failed to interpolate container.credentials.password\")\n\t\treturn \"\", \"\", err\n\t}\n\n\tif container.Credentials[\"username\"] == \"\" || container.Credentials[\"password\"] == \"\" {\n\t\terr := fmt.Errorf(\"container.credentials cannot be empty\")\n\t\treturn \"\", \"\", err\n\t}\n\n\treturn username, password, nil\n}\n\nfunc (rc *RunContext) handleServiceCredentials(ctx context.Context, creds map[string]string) (username, password string, err error) {\n\tif creds == nil {\n\t\treturn\n\t}\n\tif len(creds) != 2 {\n\t\terr = fmt.Errorf(\"invalid property count for key 'credentials:'\")\n\t\treturn\n\t}\n\n\tee := rc.NewExpressionEvaluator(ctx)\n\tif username = ee.Interpolate(ctx, creds[\"username\"]); username == \"\" {\n\t\terr = fmt.Errorf(\"failed to interpolate credentials.username\")\n\t\treturn\n\t}\n\n\tif password = ee.Interpolate(ctx, creds[\"password\"]); password == \"\" {\n\t\terr = fmt.Errorf(\"failed to interpolate credentials.password\")\n\t\treturn\n\t}\n\n\treturn\n}\n\n// GetServiceBindsAndMounts returns the binds and mounts for the service container, resolving paths as appropriate\nfunc (rc *RunContext) GetServiceBindsAndMounts(svcVolumes []string) ([]string, map[string]string) {\n\tif rc.Config.ContainerDaemonSocket == \"\" {\n\t\trc.Config.ContainerDaemonSocket = \"/var/run/docker.sock\"\n\t}\n\tbinds := []string{}\n\tif rc.Config.ContainerDaemonSocket != \"-\" {\n\t\tdaemonPath := getDockerDaemonSocketMountPath(rc.Config.ContainerDaemonSocket)\n\t\tbinds = append(binds, fmt.Sprintf(\"%s:%s\", daemonPath, \"/var/run/docker.sock\"))\n\t}\n\n\tmounts := map[string]string{}\n\n\tfor _, v := range svcVolumes {\n\t\tif !strings.Contains(v, \":\") || filepath.IsAbs(v) {\n\t\t\t// Bind anonymous volume or host file.\n\t\t\tbinds = append(binds, v)\n\t\t} else {\n\t\t\t// Mount existing volume.\n\t\t\tpaths := strings.SplitN(v, \":\", 2)\n\t\t\tmounts[paths[0]] = paths[1]\n\t\t}\n\t}\n\n\treturn binds, mounts\n}\n"
  },
  {
    "path": "pkg/runner/run_context_test.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/golang-jwt/jwt/v5\"\n\t\"github.com/nektos/act/pkg/exprparser\"\n\t\"github.com/nektos/act/pkg/model\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\tassert \"github.com/stretchr/testify/assert\"\n\tyaml \"gopkg.in/yaml.v3\"\n)\n\nfunc TestRunContext_EvalBool(t *testing.T) {\n\tvar yml yaml.Node\n\terr := yml.Encode(map[string][]interface{}{\n\t\t\"os\":  {\"Linux\", \"Windows\"},\n\t\t\"foo\": {\"bar\", \"baz\"},\n\t})\n\tassert.NoError(t, err)\n\n\trc := &RunContext{\n\t\tConfig: &Config{\n\t\t\tWorkdir: \".\",\n\t\t},\n\t\tEnv: map[string]string{\n\t\t\t\"SOMETHING_TRUE\":  \"true\",\n\t\t\t\"SOMETHING_FALSE\": \"false\",\n\t\t\t\"SOME_TEXT\":       \"text\",\n\t\t},\n\t\tRun: &model.Run{\n\t\t\tJobID: \"job1\",\n\t\t\tWorkflow: &model.Workflow{\n\t\t\t\tName: \"test-workflow\",\n\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\"job1\": {\n\t\t\t\t\t\tStrategy: &model.Strategy{\n\t\t\t\t\t\t\tRawMatrix: yml,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tMatrix: map[string]interface{}{\n\t\t\t\"os\":  \"Linux\",\n\t\t\t\"foo\": \"bar\",\n\t\t},\n\t\tStepResults: map[string]*model.StepResult{\n\t\t\t\"id1\": {\n\t\t\t\tConclusion: model.StepStatusSuccess,\n\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\tOutputs: map[string]string{\n\t\t\t\t\t\"foo\": \"bar\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\trc.ExprEval = rc.NewExpressionEvaluator(context.Background())\n\n\ttables := []struct {\n\t\tin      string\n\t\tout     bool\n\t\twantErr bool\n\t}{\n\t\t// The basic ones\n\t\t{in: \"failure()\", out: false},\n\t\t{in: \"success()\", out: true},\n\t\t{in: \"cancelled()\", out: false},\n\t\t{in: \"always()\", out: true},\n\t\t// TODO: move to sc.NewExpressionEvaluator(), because \"steps\" context is not available here\n\t\t// {in: \"steps.id1.conclusion == 'success'\", out: true},\n\t\t// {in: \"steps.id1.conclusion != 'success'\", out: false},\n\t\t// {in: \"steps.id1.outcome == 'failure'\", out: true},\n\t\t// {in: \"steps.id1.outcome != 'failure'\", out: false},\n\t\t{in: \"true\", out: true},\n\t\t{in: \"false\", out: false},\n\t\t// TODO: This does not throw an error, because the evaluator does not know if the expression is inside ${{ }} or not\n\t\t// {in: \"!true\", wantErr: true},\n\t\t// {in: \"!false\", wantErr: true},\n\t\t{in: \"1 != 0\", out: true},\n\t\t{in: \"1 != 1\", out: false},\n\t\t{in: \"${{ 1 != 0 }}\", out: true},\n\t\t{in: \"${{ 1 != 1 }}\", out: false},\n\t\t{in: \"1 == 0\", out: false},\n\t\t{in: \"1 == 1\", out: true},\n\t\t{in: \"1 > 2\", out: false},\n\t\t{in: \"1 < 2\", out: true},\n\t\t// And or\n\t\t{in: \"true && false\", out: false},\n\t\t{in: \"true && 1 < 2\", out: true},\n\t\t{in: \"false || 1 < 2\", out: true},\n\t\t{in: \"false || false\", out: false},\n\t\t// None boolable\n\t\t{in: \"env.UNKNOWN == 'true'\", out: false},\n\t\t{in: \"env.UNKNOWN\", out: false},\n\t\t// Inline expressions\n\t\t{in: \"env.SOME_TEXT\", out: true},\n\t\t{in: \"env.SOME_TEXT == 'text'\", out: true},\n\t\t{in: \"env.SOMETHING_TRUE == 'true'\", out: true},\n\t\t{in: \"env.SOMETHING_FALSE == 'true'\", out: false},\n\t\t{in: \"env.SOMETHING_TRUE\", out: true},\n\t\t{in: \"env.SOMETHING_FALSE\", out: true},\n\t\t// TODO: This does not throw an error, because the evaluator does not know if the expression is inside ${{ }} or not\n\t\t// {in: \"!env.SOMETHING_TRUE\", wantErr: true},\n\t\t// {in: \"!env.SOMETHING_FALSE\", wantErr: true},\n\t\t{in: \"${{ !env.SOMETHING_TRUE }}\", out: false},\n\t\t{in: \"${{ !env.SOMETHING_FALSE }}\", out: false},\n\t\t{in: \"${{ ! env.SOMETHING_TRUE }}\", out: false},\n\t\t{in: \"${{ ! env.SOMETHING_FALSE }}\", out: false},\n\t\t{in: \"${{ env.SOMETHING_TRUE }}\", out: true},\n\t\t{in: \"${{ env.SOMETHING_FALSE }}\", out: true},\n\t\t{in: \"${{ !env.SOMETHING_TRUE }}\", out: false},\n\t\t{in: \"${{ !env.SOMETHING_FALSE }}\", out: false},\n\t\t{in: \"${{ !env.SOMETHING_TRUE && true }}\", out: false},\n\t\t{in: \"${{ !env.SOMETHING_FALSE && true }}\", out: false},\n\t\t{in: \"${{ !env.SOMETHING_TRUE || true }}\", out: true},\n\t\t{in: \"${{ !env.SOMETHING_FALSE || false }}\", out: false},\n\t\t{in: \"${{ env.SOMETHING_TRUE && true }}\", out: true},\n\t\t{in: \"${{ env.SOMETHING_FALSE || true }}\", out: true},\n\t\t{in: \"${{ env.SOMETHING_FALSE || false }}\", out: true},\n\t\t// TODO: This does not throw an error, because the evaluator does not know if the expression is inside ${{ }} or not\n\t\t// {in: \"!env.SOMETHING_TRUE || true\", wantErr: true},\n\t\t{in: \"${{ env.SOMETHING_TRUE == 'true'}}\", out: true},\n\t\t{in: \"${{ env.SOMETHING_FALSE == 'true'}}\", out: false},\n\t\t{in: \"${{ env.SOMETHING_FALSE == 'false'}}\", out: true},\n\t\t{in: \"${{ env.SOMETHING_FALSE }} && ${{ env.SOMETHING_TRUE }}\", out: true},\n\n\t\t// All together now\n\t\t{in: \"false || env.SOMETHING_TRUE == 'true'\", out: true},\n\t\t{in: \"true || env.SOMETHING_FALSE == 'true'\", out: true},\n\t\t{in: \"true && env.SOMETHING_TRUE == 'true'\", out: true},\n\t\t{in: \"false && env.SOMETHING_TRUE == 'true'\", out: false},\n\t\t{in: \"env.SOMETHING_FALSE == 'true' && env.SOMETHING_TRUE == 'true'\", out: false},\n\t\t{in: \"env.SOMETHING_FALSE == 'true' && true\", out: false},\n\t\t{in: \"${{ env.SOMETHING_FALSE == 'true' }} && true\", out: true},\n\t\t{in: \"true && ${{ env.SOMETHING_FALSE == 'true' }}\", out: true},\n\t\t// Check github context\n\t\t{in: \"github.actor == 'nektos/act'\", out: true},\n\t\t{in: \"github.actor == 'unknown'\", out: false},\n\t\t{in: \"github.job == 'job1'\", out: true},\n\t\t// The special ACT flag\n\t\t{in: \"${{ env.ACT }}\", out: true},\n\t\t{in: \"${{ !env.ACT }}\", out: false},\n\t\t// Invalid expressions should be reported\n\t\t{in: \"INVALID_EXPRESSION\", wantErr: true},\n\t}\n\n\tupdateTestIfWorkflow(t, tables, rc)\n\tfor _, table := range tables {\n\t\tt.Run(table.in, func(t *testing.T) {\n\t\t\tassertObject := assert.New(t)\n\t\t\tb, err := EvalBool(context.Background(), rc.ExprEval, table.in, exprparser.DefaultStatusCheckSuccess)\n\t\t\tif table.wantErr {\n\t\t\t\tassertObject.Error(err)\n\t\t\t}\n\n\t\t\tassertObject.Equal(table.out, b, fmt.Sprintf(\"Expected %s to be %v, was %v\", table.in, table.out, b))\n\t\t})\n\t}\n}\n\nfunc updateTestIfWorkflow(t *testing.T, tables []struct {\n\tin      string\n\tout     bool\n\twantErr bool\n}, rc *RunContext) {\n\tvar envs string\n\tkeys := make([]string, 0, len(rc.Env))\n\tfor k := range rc.Env {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\tfor _, k := range keys {\n\t\tenvs += fmt.Sprintf(\"  %s: %s\\n\", k, rc.Env[k])\n\t}\n\t// editorconfig-checker-disable\n\tworkflow := fmt.Sprintf(`\nname: \"Test what expressions result in true and false on GitHub\"\non: push\n\nenv:\n%s\n\njobs:\n  test-ifs-and-buts:\n    runs-on: ubuntu-latest\n    steps:\n`, envs)\n\t// editorconfig-checker-enable\n\n\tfor i, table := range tables {\n\t\tif table.wantErr || strings.HasPrefix(table.in, \"github.actor\") {\n\t\t\tcontinue\n\t\t}\n\t\texpressionPattern := regexp.MustCompile(`\\${{\\s*(.+?)\\s*}}`)\n\n\t\texpr := expressionPattern.ReplaceAllStringFunc(table.in, func(match string) string {\n\t\t\treturn fmt.Sprintf(\"€{{ %s }}\", expressionPattern.ReplaceAllString(match, \"$1\"))\n\t\t})\n\t\techo := fmt.Sprintf(`run: echo \"%s should be false, but was evaluated to true;\" exit 1;`, table.in)\n\t\tname := fmt.Sprintf(`\"❌ I should not run, expr: %s\"`, expr)\n\t\tif table.out {\n\t\t\techo = `run: echo OK`\n\t\t\tname = fmt.Sprintf(`\"✅ I should run, expr: %s\"`, expr)\n\t\t}\n\t\tworkflow += fmt.Sprintf(\"\\n      - name: %s\\n        id: step%d\\n        if: %s\\n        %s\\n\", name, i, table.in, echo)\n\t\tif table.out {\n\t\t\tworkflow += fmt.Sprintf(\"\\n      - name: \\\"Double checking expr: %s\\\"\\n        if: steps.step%d.conclusion == 'skipped'\\n        run: echo \\\"%s should have been true, but wasn't\\\"\\n\", expr, i, table.in)\n\t\t}\n\t}\n\n\tfile, err := os.Create(\"../../.github/workflows/test-if.yml\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t_, err = file.WriteString(workflow)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestRunContext_GetBindsAndMounts(t *testing.T) {\n\trctemplate := &RunContext{\n\t\tName: \"TestRCName\",\n\t\tRun: &model.Run{\n\t\t\tWorkflow: &model.Workflow{\n\t\t\t\tName: \"TestWorkflowName\",\n\t\t\t},\n\t\t},\n\t\tConfig: &Config{\n\t\t\tBindWorkdir: false,\n\t\t},\n\t}\n\n\ttests := []struct {\n\t\twindowsPath bool\n\t\tname        string\n\t\trc          *RunContext\n\t\twantbind    string\n\t\twantmount   string\n\t}{\n\t\t{false, \"/mnt/linux\", rctemplate, \"/mnt/linux\", \"/mnt/linux\"},\n\t\t{false, \"/mnt/path with spaces/linux\", rctemplate, \"/mnt/path with spaces/linux\", \"/mnt/path with spaces/linux\"},\n\t\t{true, \"C:\\\\Users\\\\TestPath\\\\MyTestPath\", rctemplate, \"/mnt/c/Users/TestPath/MyTestPath\", \"/mnt/c/Users/TestPath/MyTestPath\"},\n\t\t{true, \"C:\\\\Users\\\\Test Path with Spaces\\\\MyTestPath\", rctemplate, \"/mnt/c/Users/Test Path with Spaces/MyTestPath\", \"/mnt/c/Users/Test Path with Spaces/MyTestPath\"},\n\t\t{true, \"/LinuxPathOnWindowsShouldFail\", rctemplate, \"\", \"\"},\n\t}\n\n\tisWindows := runtime.GOOS == \"windows\"\n\n\tfor _, testcase := range tests {\n\t\tfor _, bindWorkDir := range []bool{true, false} {\n\t\t\ttestBindSuffix := \"\"\n\t\t\tif bindWorkDir {\n\t\t\t\ttestBindSuffix = \"Bind\"\n\t\t\t}\n\n\t\t\t// Only run windows path tests on windows and non-windows on non-windows\n\t\t\tif (isWindows && testcase.windowsPath) || (!isWindows && !testcase.windowsPath) {\n\t\t\t\tt.Run((testcase.name + testBindSuffix), func(t *testing.T) {\n\t\t\t\t\tconfig := testcase.rc.Config\n\t\t\t\t\tconfig.Workdir = testcase.name\n\t\t\t\t\tconfig.BindWorkdir = bindWorkDir\n\t\t\t\t\tgotbind, gotmount := rctemplate.GetBindsAndMounts()\n\n\t\t\t\t\t// Name binds/mounts are either/or\n\t\t\t\t\tif config.BindWorkdir {\n\t\t\t\t\t\tfullBind := testcase.name + \":\" + testcase.wantbind\n\t\t\t\t\t\tif runtime.GOOS == \"darwin\" {\n\t\t\t\t\t\t\tfullBind += \":delegated\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tassert.Contains(t, gotbind, fullBind)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmountkey := testcase.rc.jobContainerName()\n\t\t\t\t\t\tassert.EqualValues(t, testcase.wantmount, gotmount[mountkey])\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\tt.Run(\"ContainerVolumeMountTest\", func(t *testing.T) {\n\t\ttests := []struct {\n\t\t\tname      string\n\t\t\tvolumes   []string\n\t\t\twantbind  string\n\t\t\twantmount map[string]string\n\t\t}{\n\t\t\t{\"BindAnonymousVolume\", []string{\"/volume\"}, \"/volume\", map[string]string{}},\n\t\t\t{\"BindHostFile\", []string{\"/path/to/file/on/host:/volume\"}, \"/path/to/file/on/host:/volume\", map[string]string{}},\n\t\t\t{\"MountExistingVolume\", []string{\"volume-id:/volume\"}, \"\", map[string]string{\"volume-id\": \"/volume\"}},\n\t\t}\n\n\t\tfor _, testcase := range tests {\n\t\t\tt.Run(testcase.name, func(t *testing.T) {\n\t\t\t\tjob := &model.Job{}\n\t\t\t\terr := job.RawContainer.Encode(map[string][]string{\n\t\t\t\t\t\"volumes\": testcase.volumes,\n\t\t\t\t})\n\t\t\t\tassert.NoError(t, err)\n\n\t\t\t\trc := &RunContext{\n\t\t\t\t\tName: \"TestRCName\",\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tName: \"TestWorkflowName\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tConfig: &Config{\n\t\t\t\t\t\tBindWorkdir: false,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\trc.Run.JobID = \"job1\"\n\t\t\t\trc.Run.Workflow.Jobs = map[string]*model.Job{\"job1\": job}\n\n\t\t\t\tgotbind, gotmount := rc.GetBindsAndMounts()\n\n\t\t\t\tif len(testcase.wantbind) > 0 {\n\t\t\t\t\tassert.Contains(t, gotbind, testcase.wantbind)\n\t\t\t\t}\n\n\t\t\t\tfor k, v := range testcase.wantmount {\n\t\t\t\t\tassert.Contains(t, gotmount, k)\n\t\t\t\t\tassert.Equal(t, gotmount[k], v)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestGetGitHubContext(t *testing.T) {\n\tlog.SetLevel(log.DebugLevel)\n\n\tcwd, err := os.Getwd()\n\tassert.Nil(t, err)\n\n\trc := &RunContext{\n\t\tConfig: &Config{\n\t\t\tEventName: \"push\",\n\t\t\tWorkdir:   cwd,\n\t\t},\n\t\tRun: &model.Run{\n\t\t\tWorkflow: &model.Workflow{\n\t\t\t\tName: \"GitHubContextTest\",\n\t\t\t},\n\t\t},\n\t\tName:           \"GitHubContextTest\",\n\t\tCurrentStep:    \"step\",\n\t\tMatrix:         map[string]interface{}{},\n\t\tEnv:            map[string]string{},\n\t\tExtraPath:      []string{},\n\t\tStepResults:    map[string]*model.StepResult{},\n\t\tOutputMappings: map[MappableOutput]MappableOutput{},\n\t}\n\trc.Run.JobID = \"job1\"\n\n\tghc := rc.getGithubContext(context.Background())\n\n\tlog.Debugf(\"%v\", ghc)\n\n\tactor := \"nektos/act\"\n\tif a := os.Getenv(\"ACT_ACTOR\"); a != \"\" {\n\t\tactor = a\n\t}\n\n\trepo := \"nektos/act\"\n\tif r := os.Getenv(\"ACT_REPOSITORY\"); r != \"\" {\n\t\trepo = r\n\t}\n\n\towner := \"nektos\"\n\tif o := os.Getenv(\"ACT_OWNER\"); o != \"\" {\n\t\towner = o\n\t}\n\n\tassert.Equal(t, \"1\", ghc.RunID)\n\tassert.Equal(t, \"1\", ghc.RunNumber)\n\tassert.Equal(t, \"0\", ghc.RetentionDays)\n\tassert.Equal(t, actor, ghc.Actor)\n\tassert.Equal(t, repo, ghc.Repository)\n\tassert.Equal(t, owner, ghc.RepositoryOwner)\n\tassert.Equal(t, \"/dev/null\", ghc.RunnerPerflog)\n\tassert.Equal(t, rc.Config.Secrets[\"GITHUB_TOKEN\"], ghc.Token)\n\tassert.Equal(t, \"job1\", ghc.Job)\n}\n\nfunc TestGetGithubContextRef(t *testing.T) {\n\ttable := []struct {\n\t\tevent string\n\t\tjson  string\n\t\tref   string\n\t}{\n\t\t{event: \"push\", json: `{\"ref\":\"0000000000000000000000000000000000000000\"}`, ref: \"0000000000000000000000000000000000000000\"},\n\t\t{event: \"create\", json: `{\"ref\":\"0000000000000000000000000000000000000000\"}`, ref: \"0000000000000000000000000000000000000000\"},\n\t\t{event: \"workflow_dispatch\", json: `{\"ref\":\"0000000000000000000000000000000000000000\"}`, ref: \"0000000000000000000000000000000000000000\"},\n\t\t{event: \"delete\", json: `{\"repository\":{\"default_branch\": \"main\"}}`, ref: \"refs/heads/main\"},\n\t\t{event: \"pull_request\", json: `{\"number\":123}`, ref: \"refs/pull/123/merge\"},\n\t\t{event: \"pull_request_review\", json: `{\"number\":123}`, ref: \"refs/pull/123/merge\"},\n\t\t{event: \"pull_request_review_comment\", json: `{\"number\":123}`, ref: \"refs/pull/123/merge\"},\n\t\t{event: \"pull_request_target\", json: `{\"pull_request\":{\"base\":{\"ref\": \"main\"}}}`, ref: \"refs/heads/main\"},\n\t\t{event: \"deployment\", json: `{\"deployment\": {\"ref\": \"tag-name\"}}`, ref: \"tag-name\"},\n\t\t{event: \"deployment_status\", json: `{\"deployment\": {\"ref\": \"tag-name\"}}`, ref: \"tag-name\"},\n\t\t{event: \"release\", json: `{\"release\": {\"tag_name\": \"tag-name\"}}`, ref: \"refs/tags/tag-name\"},\n\t}\n\n\tfor _, data := range table {\n\t\tt.Run(data.event, func(t *testing.T) {\n\t\t\trc := &RunContext{\n\t\t\t\tEventJSON: data.json,\n\t\t\t\tConfig: &Config{\n\t\t\t\t\tEventName: data.event,\n\t\t\t\t\tWorkdir:   \"\",\n\t\t\t\t},\n\t\t\t\tRun: &model.Run{\n\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\tName: \"GitHubContextTest\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tghc := rc.getGithubContext(context.Background())\n\n\t\t\tassert.Equal(t, data.ref, ghc.Ref)\n\t\t})\n\t}\n}\n\nfunc createIfTestRunContext(jobs map[string]*model.Job) *RunContext {\n\trc := &RunContext{\n\t\tConfig: &Config{\n\t\t\tWorkdir: \".\",\n\t\t\tPlatforms: map[string]string{\n\t\t\t\t\"ubuntu-latest\": \"ubuntu-latest\",\n\t\t\t},\n\t\t},\n\t\tEnv: map[string]string{},\n\t\tRun: &model.Run{\n\t\t\tJobID: \"job1\",\n\t\t\tWorkflow: &model.Workflow{\n\t\t\t\tName: \"test-workflow\",\n\t\t\t\tJobs: jobs,\n\t\t\t},\n\t\t},\n\t}\n\trc.ExprEval = rc.NewExpressionEvaluator(context.Background())\n\n\treturn rc\n}\n\nfunc createJob(t *testing.T, input string, result string) *model.Job {\n\tvar job *model.Job\n\terr := yaml.Unmarshal([]byte(input), &job)\n\tassert.NoError(t, err)\n\tjob.Result = result\n\n\treturn job\n}\n\nfunc TestRunContextRunsOnPlatformNames(t *testing.T) {\n\tlog.SetLevel(log.DebugLevel)\n\tassertObject := assert.New(t)\n\n\trc := createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"\"),\n\t})\n\tassertObject.Equal([]string{\"ubuntu-latest\"}, rc.runsOnPlatformNames(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ${{ 'ubuntu-latest' }}`, \"\"),\n\t})\n\tassertObject.Equal([]string{\"ubuntu-latest\"}, rc.runsOnPlatformNames(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: [self-hosted, my-runner]`, \"\"),\n\t})\n\tassertObject.Equal([]string{\"self-hosted\", \"my-runner\"}, rc.runsOnPlatformNames(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: [self-hosted, \"${{ 'my-runner' }}\"]`, \"\"),\n\t})\n\tassertObject.Equal([]string{\"self-hosted\", \"my-runner\"}, rc.runsOnPlatformNames(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ${{ fromJSON('[\"ubuntu-latest\"]') }}`, \"\"),\n\t})\n\tassertObject.Equal([]string{\"ubuntu-latest\"}, rc.runsOnPlatformNames(context.Background()))\n\n\t// test missing / invalid runs-on\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `name: something`, \"\"),\n\t})\n\tassertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on:\n  mapping: value`, \"\"),\n\t})\n\tassertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ${{ invalid expression }}`, \"\"),\n\t})\n\tassertObject.Equal([]string{}, rc.runsOnPlatformNames(context.Background()))\n}\n\nfunc TestRunContextIsEnabled(t *testing.T) {\n\tlog.SetLevel(log.DebugLevel)\n\tassertObject := assert.New(t)\n\n\t// success()\n\trc := createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest\nif: success()`, \"\"),\n\t})\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"failure\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nneeds: [job1]\nif: success()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.False(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"success\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nneeds: [job1]\nif: success()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"failure\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nif: success()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\t// failure()\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest\nif: failure()`, \"\"),\n\t})\n\tassertObject.False(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"failure\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nneeds: [job1]\nif: failure()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"success\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nneeds: [job1]\nif: failure()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.False(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"failure\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nif: failure()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.False(rc.isEnabled(context.Background()))\n\n\t// always()\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest\nif: always()`, \"\"),\n\t})\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"failure\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nneeds: [job1]\nif: always()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"success\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nneeds: [job1]\nif: always()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"success\"),\n\t\t\"job2\": createJob(t, `runs-on: ubuntu-latest\nif: always()`, \"\"),\n\t})\n\trc.Run.JobID = \"job2\"\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `uses: ./.github/workflows/reusable.yml`, \"\"),\n\t})\n\tassertObject.True(rc.isEnabled(context.Background()))\n\n\trc = createIfTestRunContext(map[string]*model.Job{\n\t\t\"job1\": createJob(t, `uses: ./.github/workflows/reusable.yml\nif: false`, \"\"),\n\t})\n\tassertObject.False(rc.isEnabled(context.Background()))\n}\n\nfunc TestRunContextGetEnv(t *testing.T) {\n\ttests := []struct {\n\t\tdescription string\n\t\trc          *RunContext\n\t\ttargetEnv   string\n\t\twant        string\n\t}{\n\t\t{\n\t\t\tdescription: \"Env from Config should overwrite\",\n\t\t\trc: &RunContext{\n\t\t\t\tConfig: &Config{\n\t\t\t\t\tEnv: map[string]string{\"OVERWRITTEN\": \"true\"},\n\t\t\t\t},\n\t\t\t\tRun: &model.Run{\n\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\tJobs: map[string]*model.Job{\"test\": {Name: \"test\"}},\n\t\t\t\t\t\tEnv:  map[string]string{\"OVERWRITTEN\": \"false\"},\n\t\t\t\t\t},\n\t\t\t\t\tJobID: \"test\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttargetEnv: \"OVERWRITTEN\",\n\t\t\twant:      \"true\",\n\t\t},\n\t\t{\n\t\t\tdescription: \"No overwrite occurs\",\n\t\t\trc: &RunContext{\n\t\t\t\tConfig: &Config{\n\t\t\t\t\tEnv: map[string]string{\"SOME_OTHER_VAR\": \"true\"},\n\t\t\t\t},\n\t\t\t\tRun: &model.Run{\n\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\tJobs: map[string]*model.Job{\"test\": {Name: \"test\"}},\n\t\t\t\t\t\tEnv:  map[string]string{\"OVERWRITTEN\": \"false\"},\n\t\t\t\t\t},\n\t\t\t\t\tJobID: \"test\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttargetEnv: \"OVERWRITTEN\",\n\t\t\twant:      \"false\",\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.description, func(t *testing.T) {\n\t\t\tenvMap := test.rc.GetEnv()\n\t\t\tassert.EqualValues(t, test.want, envMap[test.targetEnv])\n\t\t})\n\t}\n}\n\nfunc TestSetRuntimeVariables(t *testing.T) {\n\trc := &RunContext{\n\t\tConfig: &Config{\n\t\t\tArtifactServerAddr: \"myhost\",\n\t\t\tArtifactServerPort: \"8000\",\n\t\t},\n\t}\n\tv := \"http://myhost:8000/\"\n\tenv := map[string]string{}\n\tsetActionRuntimeVars(rc, env)\n\n\tassert.Equal(t, v, env[\"ACTIONS_RESULTS_URL\"])\n\tassert.Equal(t, v, env[\"ACTIONS_RUNTIME_URL\"])\n\truntimeToken := env[\"ACTIONS_RUNTIME_TOKEN\"]\n\tassert.NotEmpty(t, v, runtimeToken)\n\n\ttkn, _, err := jwt.NewParser().ParseUnverified(runtimeToken, jwt.MapClaims{})\n\tassert.NotNil(t, tkn)\n\tassert.Nil(t, err)\n}\n\nfunc TestSetRuntimeVariablesWithRunID(t *testing.T) {\n\trc := &RunContext{\n\t\tConfig: &Config{\n\t\t\tArtifactServerAddr: \"myhost\",\n\t\t\tArtifactServerPort: \"8000\",\n\t\t\tEnv: map[string]string{\n\t\t\t\t\"GITHUB_RUN_ID\": \"45\",\n\t\t\t},\n\t\t},\n\t}\n\tv := \"http://myhost:8000/\"\n\tenv := map[string]string{}\n\tsetActionRuntimeVars(rc, env)\n\n\tassert.Equal(t, v, env[\"ACTIONS_RESULTS_URL\"])\n\tassert.Equal(t, v, env[\"ACTIONS_RUNTIME_URL\"])\n\truntimeToken := env[\"ACTIONS_RUNTIME_TOKEN\"]\n\tassert.NotEmpty(t, v, runtimeToken)\n\n\tclaims := jwt.MapClaims{}\n\ttkn, _, err := jwt.NewParser().ParseUnverified(runtimeToken, &claims)\n\tassert.NotNil(t, tkn)\n\tassert.Nil(t, err)\n\tscp, ok := claims[\"scp\"]\n\tassert.True(t, ok, \"scp claim exists\")\n\tassert.Equal(t, \"Actions.Results:45:45\", scp, \"contains expected scp claim\")\n}\n"
  },
  {
    "path": "pkg/runner/runner.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\n\tdocker_container \"github.com/docker/docker/api/types/container\"\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// Runner provides capabilities to run GitHub actions\ntype Runner interface {\n\tNewPlanExecutor(plan *model.Plan) common.Executor\n}\n\n// Config contains the config for a new runner\ntype Config struct {\n\tActor                              string                       // the user that triggered the event\n\tWorkdir                            string                       // path to working directory\n\tActionCacheDir                     string                       // path used for caching action contents\n\tActionOfflineMode                  bool                         // when offline, use caching action contents\n\tBindWorkdir                        bool                         // bind the workdir to the job container\n\tEventName                          string                       // name of event to run\n\tEventPath                          string                       // path to JSON file to use for event.json in containers\n\tDefaultBranch                      string                       // name of the main branch for this repository\n\tReuseContainers                    bool                         // reuse containers to maintain state\n\tForcePull                          bool                         // force pulling of the image, even if already present\n\tForceRebuild                       bool                         // force rebuilding local docker image action\n\tLogOutput                          bool                         // log the output from docker run\n\tJSONLogger                         bool                         // use json or text logger\n\tLogPrefixJobID                     bool                         // switches from the full job name to the job id\n\tEnv                                map[string]string            // env for containers\n\tInputs                             map[string]string            // manually passed action inputs\n\tSecrets                            map[string]string            // list of secrets\n\tVars                               map[string]string            // list of vars\n\tToken                              string                       // GitHub token\n\tInsecureSecrets                    bool                         // switch hiding output when printing to terminal\n\tPlatforms                          map[string]string            // list of platforms\n\tPrivileged                         bool                         // use privileged mode\n\tUsernsMode                         string                       // user namespace to use\n\tContainerArchitecture              string                       // Desired OS/architecture platform for running containers\n\tContainerDaemonSocket              string                       // Path to Docker daemon socket\n\tContainerOptions                   string                       // Options for the job container\n\tUseGitIgnore                       bool                         // controls if paths in .gitignore should not be copied into container, default true\n\tGitHubInstance                     string                       // GitHub instance to use, default \"github.com\"\n\tContainerCapAdd                    []string                     // list of kernel capabilities to add to the containers\n\tContainerCapDrop                   []string                     // list of kernel capabilities to remove from the containers\n\tAutoRemove                         bool                         // controls if the container is automatically removed upon workflow completion\n\tArtifactServerPath                 string                       // the path where the artifact server stores uploads\n\tArtifactServerAddr                 string                       // the address the artifact server binds to\n\tArtifactServerPort                 string                       // the port the artifact server binds to\n\tNoSkipCheckout                     bool                         // do not skip actions/checkout\n\tRemoteName                         string                       // remote name in local git repo config\n\tReplaceGheActionWithGithubCom      []string                     // Use actions from GitHub Enterprise instance to GitHub\n\tReplaceGheActionTokenWithGithubCom string                       // Token of private action repo on GitHub.\n\tMatrix                             map[string]map[string]bool   // Matrix config to run\n\tContainerNetworkMode               docker_container.NetworkMode // the network mode of job containers (the value of --network)\n\tActionCache                        ActionCache                  // Use a custom ActionCache Implementation\n\tConcurrentJobs                     int                          // Number of max concurrent jobs\n}\n\nfunc (config *Config) GetConcurrentJobs() int {\n\tif config.ConcurrentJobs >= 1 {\n\t\treturn config.ConcurrentJobs\n\t}\n\n\tncpu := runtime.NumCPU()\n\tlog.Debugf(\"Detected CPUs: %d\", ncpu)\n\tif ncpu > 1 {\n\t\treturn ncpu\n\t}\n\treturn 1\n}\n\ntype caller struct {\n\trunContext *RunContext\n}\n\ntype runnerImpl struct {\n\tconfig    *Config\n\teventJSON string\n\tcaller    *caller // the job calling this runner (caller of a reusable workflow)\n}\n\n// New Creates a new Runner\nfunc New(runnerConfig *Config) (Runner, error) {\n\trunner := &runnerImpl{\n\t\tconfig: runnerConfig,\n\t}\n\n\treturn runner.configure()\n}\n\nfunc (runner *runnerImpl) configure() (Runner, error) {\n\trunner.eventJSON = \"{}\"\n\tif runner.config.EventPath != \"\" {\n\t\tlog.Debugf(\"Reading event.json from %s\", runner.config.EventPath)\n\t\teventJSONBytes, err := os.ReadFile(runner.config.EventPath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trunner.eventJSON = string(eventJSONBytes)\n\t} else if len(runner.config.Inputs) != 0 {\n\t\teventMap := map[string]map[string]string{\n\t\t\t\"inputs\": runner.config.Inputs,\n\t\t}\n\t\teventJSON, err := json.Marshal(eventMap)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trunner.eventJSON = string(eventJSON)\n\t}\n\treturn runner, nil\n}\n\n// NewPlanExecutor ...\nfunc (runner *runnerImpl) NewPlanExecutor(plan *model.Plan) common.Executor {\n\tmaxJobNameLen := 0\n\n\tstagePipeline := make([]common.Executor, 0)\n\tlog.Debugf(\"Plan Stages: %v\", plan.Stages)\n\n\tfor i := range plan.Stages {\n\t\tstage := plan.Stages[i]\n\t\tstagePipeline = append(stagePipeline, func(ctx context.Context) error {\n\t\t\tpipeline := make([]common.Executor, 0)\n\t\t\tfor _, run := range stage.Runs {\n\t\t\t\tlog.Debugf(\"Stages Runs: %v\", stage.Runs)\n\t\t\t\tstageExecutor := make([]common.Executor, 0)\n\t\t\t\tjob := run.Job()\n\t\t\t\tlog.Debugf(\"Job.Name: %v\", job.Name)\n\t\t\t\tlog.Debugf(\"Job.RawNeeds: %v\", job.RawNeeds)\n\t\t\t\tlog.Debugf(\"Job.RawRunsOn: %v\", job.RawRunsOn)\n\t\t\t\tlog.Debugf(\"Job.Env: %v\", job.Env)\n\t\t\t\tlog.Debugf(\"Job.If: %v\", job.If)\n\t\t\t\tfor step := range job.Steps {\n\t\t\t\t\tif nil != job.Steps[step] {\n\t\t\t\t\t\tlog.Debugf(\"Job.Steps: %v\", job.Steps[step].String())\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlog.Debugf(\"Job.TimeoutMinutes: %v\", job.TimeoutMinutes)\n\t\t\t\tlog.Debugf(\"Job.Services: %v\", job.Services)\n\t\t\t\tlog.Debugf(\"Job.Strategy: %v\", job.Strategy)\n\t\t\t\tlog.Debugf(\"Job.RawContainer: %v\", job.RawContainer)\n\t\t\t\tlog.Debugf(\"Job.Defaults.Run.Shell: %v\", job.Defaults.Run.Shell)\n\t\t\t\tlog.Debugf(\"Job.Defaults.Run.WorkingDirectory: %v\", job.Defaults.Run.WorkingDirectory)\n\t\t\t\tlog.Debugf(\"Job.Outputs: %v\", job.Outputs)\n\t\t\t\tlog.Debugf(\"Job.Uses: %v\", job.Uses)\n\t\t\t\tlog.Debugf(\"Job.With: %v\", job.With)\n\t\t\t\t// log.Debugf(\"Job.RawSecrets: %v\", job.RawSecrets)\n\t\t\t\tlog.Debugf(\"Job.Result: %v\", job.Result)\n\n\t\t\t\tif job.Strategy != nil {\n\t\t\t\t\tlog.Debugf(\"Job.Strategy.FailFast: %v\", job.Strategy.FailFast)\n\t\t\t\t\tlog.Debugf(\"Job.Strategy.MaxParallel: %v\", job.Strategy.MaxParallel)\n\t\t\t\t\tlog.Debugf(\"Job.Strategy.FailFastString: %v\", job.Strategy.FailFastString)\n\t\t\t\t\tlog.Debugf(\"Job.Strategy.MaxParallelString: %v\", job.Strategy.MaxParallelString)\n\t\t\t\t\tlog.Debugf(\"Job.Strategy.RawMatrix: %v\", job.Strategy.RawMatrix)\n\n\t\t\t\t\tstrategyRc := runner.newRunContext(ctx, run, nil)\n\t\t\t\t\tif err := strategyRc.NewExpressionEvaluator(ctx).EvaluateYamlNode(ctx, &job.Strategy.RawMatrix); err != nil {\n\t\t\t\t\t\tlog.Errorf(\"Error while evaluating matrix: %v\", err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar matrixes []map[string]interface{}\n\t\t\t\tif m, err := job.GetMatrixes(); err != nil {\n\t\t\t\t\tlog.Errorf(\"Error while get job's matrix: %v\", err)\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"Job Matrices: %v\", m)\n\t\t\t\t\tlog.Debugf(\"Runner Matrices: %v\", runner.config.Matrix)\n\t\t\t\t\tmatrixes = selectMatrixes(m, runner.config.Matrix)\n\t\t\t\t}\n\t\t\t\tlog.Debugf(\"Final matrix after applying user inclusions '%v'\", matrixes)\n\n\t\t\t\tmaxParallel := 4\n\t\t\t\tif job.Strategy != nil {\n\t\t\t\t\tmaxParallel = job.Strategy.MaxParallel\n\t\t\t\t}\n\n\t\t\t\tif len(matrixes) < maxParallel {\n\t\t\t\t\tmaxParallel = len(matrixes)\n\t\t\t\t}\n\n\t\t\t\tfor i, matrix := range matrixes {\n\t\t\t\t\trc := runner.newRunContext(ctx, run, matrix)\n\t\t\t\t\trc.JobName = rc.Name\n\t\t\t\t\tif len(matrixes) > 1 {\n\t\t\t\t\t\trc.Name = fmt.Sprintf(\"%s-%d\", rc.Name, i+1)\n\t\t\t\t\t}\n\t\t\t\t\tif len(rc.String()) > maxJobNameLen {\n\t\t\t\t\t\tmaxJobNameLen = len(rc.String())\n\t\t\t\t\t}\n\t\t\t\t\tstageExecutor = append(stageExecutor, func(ctx context.Context) error {\n\t\t\t\t\t\tjobName := fmt.Sprintf(\"%-*s\", maxJobNameLen, rc.String())\n\t\t\t\t\t\texecutor, err := rc.Executor()\n\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn executor(common.WithJobErrorContainer(WithJobLogger(ctx, rc.Run.JobID, jobName, rc.Config, &rc.Masks, matrix)))\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tpipeline = append(pipeline, common.NewParallelExecutor(maxParallel, stageExecutor...))\n\t\t\t}\n\n\t\t\tlog.Debugf(\"PlanExecutor concurrency: %d\", runner.config.GetConcurrentJobs())\n\t\t\treturn common.NewParallelExecutor(runner.config.GetConcurrentJobs(), pipeline...)(ctx)\n\t\t})\n\t}\n\n\treturn common.NewPipelineExecutor(stagePipeline...).Then(handleFailure(plan))\n}\n\nfunc handleFailure(plan *model.Plan) common.Executor {\n\treturn func(_ context.Context) error {\n\t\tfor _, stage := range plan.Stages {\n\t\t\tfor _, run := range stage.Runs {\n\t\t\t\tif run.Job().Result == \"failure\" {\n\t\t\t\t\treturn fmt.Errorf(\"Job '%s' failed\", run.String())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc selectMatrixes(originalMatrixes []map[string]interface{}, targetMatrixValues map[string]map[string]bool) []map[string]interface{} {\n\tmatrixes := make([]map[string]interface{}, 0)\n\tfor _, original := range originalMatrixes {\n\t\tflag := true\n\t\tfor key, val := range original {\n\t\t\tif allowedVals, ok := targetMatrixValues[key]; ok {\n\t\t\t\tvalToString := fmt.Sprintf(\"%v\", val)\n\t\t\t\tif _, ok := allowedVals[valToString]; !ok {\n\t\t\t\t\tflag = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif flag {\n\t\t\tmatrixes = append(matrixes, original)\n\t\t}\n\t}\n\treturn matrixes\n}\n\nfunc (runner *runnerImpl) newRunContext(ctx context.Context, run *model.Run, matrix map[string]interface{}) *RunContext {\n\trc := &RunContext{\n\t\tConfig:      runner.config,\n\t\tRun:         run,\n\t\tEventJSON:   runner.eventJSON,\n\t\tStepResults: make(map[string]*model.StepResult),\n\t\tMatrix:      matrix,\n\t\tcaller:      runner.caller,\n\t}\n\trc.ExprEval = rc.NewExpressionEvaluator(ctx)\n\trc.Name = rc.ExprEval.Interpolate(ctx, run.String())\n\n\treturn rc\n}\n"
  },
  {
    "path": "pkg/runner/runner_test.go",
    "content": "package runner\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/joho/godotenv\"\n\t\"github.com/sirupsen/logrus\"\n\tlog \"github.com/sirupsen/logrus\"\n\tassert \"github.com/stretchr/testify/assert\"\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nvar (\n\tbaseImage = \"node:24-bookworm-slim\"\n\tplatforms map[string]string\n\tlogLevel  = log.DebugLevel\n\tworkdir   = \"testdata\"\n\tsecrets   map[string]string\n)\n\nfunc init() {\n\tif p := os.Getenv(\"ACT_TEST_IMAGE\"); p != \"\" {\n\t\tbaseImage = p\n\t}\n\n\tplatforms = map[string]string{\n\t\t\"ubuntu-latest\": baseImage,\n\t\t\"self-hosted\":   \"-self-hosted\",\n\t}\n\n\tif l := os.Getenv(\"ACT_TEST_LOG_LEVEL\"); l != \"\" {\n\t\tif lvl, err := log.ParseLevel(l); err == nil {\n\t\t\tlogLevel = lvl\n\t\t}\n\t}\n\n\tif wd, err := filepath.Abs(workdir); err == nil {\n\t\tworkdir = wd\n\t}\n\n\tsecrets = map[string]string{}\n}\n\nfunc TestNoWorkflowsFoundByPlanner(t *testing.T) {\n\tplanner, err := model.NewWorkflowPlanner(\"res\", true, false)\n\tassert.NoError(t, err)\n\n\tout := log.StandardLogger().Out\n\tvar buf bytes.Buffer\n\tlog.SetOutput(&buf)\n\tlog.SetLevel(log.DebugLevel)\n\tplan, err := planner.PlanEvent(\"pull_request\")\n\tassert.NotNil(t, plan)\n\tassert.NoError(t, err)\n\tassert.Contains(t, buf.String(), \"no workflows found by planner\")\n\tbuf.Reset()\n\tplan, err = planner.PlanAll()\n\tassert.NotNil(t, plan)\n\tassert.NoError(t, err)\n\tassert.Contains(t, buf.String(), \"no workflows found by planner\")\n\tlog.SetOutput(out)\n}\n\nfunc TestGraphMissingEvent(t *testing.T) {\n\tplanner, err := model.NewWorkflowPlanner(\"testdata/issue-1595/no-event.yml\", true, false)\n\tassert.NoError(t, err)\n\n\tout := log.StandardLogger().Out\n\tvar buf bytes.Buffer\n\tlog.SetOutput(&buf)\n\tlog.SetLevel(log.DebugLevel)\n\n\tplan, err := planner.PlanEvent(\"push\")\n\tassert.NoError(t, err)\n\tassert.NotNil(t, plan)\n\tassert.Equal(t, 0, len(plan.Stages))\n\n\tassert.Contains(t, buf.String(), \"no events found for workflow: no-event.yml\")\n\tlog.SetOutput(out)\n}\n\nfunc TestGraphMissingFirst(t *testing.T) {\n\tplanner, err := model.NewWorkflowPlanner(\"testdata/issue-1595/no-first.yml\", true, false)\n\tassert.NoError(t, err)\n\n\tplan, err := planner.PlanEvent(\"push\")\n\tassert.EqualError(t, err, \"unable to build dependency graph for no first (no-first.yml)\")\n\tassert.NotNil(t, plan)\n\tassert.Equal(t, 0, len(plan.Stages))\n}\n\nfunc TestGraphWithMissing(t *testing.T) {\n\tplanner, err := model.NewWorkflowPlanner(\"testdata/issue-1595/missing.yml\", true, false)\n\tassert.NoError(t, err)\n\n\tout := log.StandardLogger().Out\n\tvar buf bytes.Buffer\n\tlog.SetOutput(&buf)\n\tlog.SetLevel(log.DebugLevel)\n\n\tplan, err := planner.PlanEvent(\"push\")\n\tassert.NotNil(t, plan)\n\tassert.Equal(t, 0, len(plan.Stages))\n\tassert.EqualError(t, err, \"unable to build dependency graph for missing (missing.yml)\")\n\tassert.Contains(t, buf.String(), \"unable to build dependency graph for missing (missing.yml)\")\n\tlog.SetOutput(out)\n}\n\nfunc TestGraphWithSomeMissing(t *testing.T) {\n\tlog.SetLevel(log.DebugLevel)\n\n\tplanner, err := model.NewWorkflowPlanner(\"testdata/issue-1595/\", true, false)\n\tassert.NoError(t, err)\n\n\tout := log.StandardLogger().Out\n\tvar buf bytes.Buffer\n\tlog.SetOutput(&buf)\n\tlog.SetLevel(log.DebugLevel)\n\n\tplan, err := planner.PlanAll()\n\tassert.Error(t, err, \"unable to build dependency graph for no first (no-first.yml)\")\n\tassert.NotNil(t, plan)\n\tassert.Equal(t, 1, len(plan.Stages))\n\tassert.Contains(t, buf.String(), \"unable to build dependency graph for missing (missing.yml)\")\n\tassert.Contains(t, buf.String(), \"unable to build dependency graph for no first (no-first.yml)\")\n\tlog.SetOutput(out)\n}\n\nfunc TestGraphEvent(t *testing.T) {\n\tplanner, err := model.NewWorkflowPlanner(\"testdata/basic\", true, false)\n\tassert.NoError(t, err)\n\n\tplan, err := planner.PlanEvent(\"push\")\n\tassert.NoError(t, err)\n\tassert.NotNil(t, plan)\n\tassert.NotNil(t, plan.Stages)\n\tassert.Equal(t, len(plan.Stages), 3, \"stages\")\n\tassert.Equal(t, len(plan.Stages[0].Runs), 1, \"stage0.runs\")\n\tassert.Equal(t, len(plan.Stages[1].Runs), 1, \"stage1.runs\")\n\tassert.Equal(t, len(plan.Stages[2].Runs), 1, \"stage2.runs\")\n\tassert.Equal(t, plan.Stages[0].Runs[0].JobID, \"check\", \"jobid\")\n\tassert.Equal(t, plan.Stages[1].Runs[0].JobID, \"build\", \"jobid\")\n\tassert.Equal(t, plan.Stages[2].Runs[0].JobID, \"test\", \"jobid\")\n\n\tplan, err = planner.PlanEvent(\"release\")\n\tassert.NoError(t, err)\n\tassert.NotNil(t, plan)\n\tassert.Equal(t, 0, len(plan.Stages))\n}\n\ntype TestJobFileInfo struct {\n\tworkdir      string\n\tworkflowPath string\n\teventName    string\n\terrorMessage string\n\tplatforms    map[string]string\n\tsecrets      map[string]string\n}\n\nfunc (j *TestJobFileInfo) runTest(ctx context.Context, t *testing.T, cfg *Config) {\n\tfmt.Printf(\"::group::%s\\n\", j.workflowPath)\n\n\tlog.SetLevel(logLevel)\n\n\tworkdir, err := filepath.Abs(j.workdir)\n\tassert.Nil(t, err, workdir)\n\n\tfullWorkflowPath := filepath.Join(workdir, j.workflowPath)\n\trunnerConfig := &Config{\n\t\tWorkdir:               workdir,\n\t\tBindWorkdir:           false,\n\t\tEventName:             j.eventName,\n\t\tEventPath:             cfg.EventPath,\n\t\tPlatforms:             j.platforms,\n\t\tReuseContainers:       false,\n\t\tEnv:                   cfg.Env,\n\t\tSecrets:               cfg.Secrets,\n\t\tInputs:                cfg.Inputs,\n\t\tGitHubInstance:        \"github.com\",\n\t\tContainerArchitecture: cfg.ContainerArchitecture,\n\t\tMatrix:                cfg.Matrix,\n\t\tActionCache:           cfg.ActionCache,\n\t}\n\n\trunner, err := New(runnerConfig)\n\tassert.Nil(t, err, j.workflowPath)\n\n\tplanner, err := model.NewWorkflowPlanner(fullWorkflowPath, true, false)\n\tif j.errorMessage != \"\" && err != nil {\n\t\tassert.Error(t, err, j.errorMessage)\n\t} else if assert.Nil(t, err, fullWorkflowPath) {\n\t\tplan, err := planner.PlanEvent(j.eventName)\n\t\tassert.True(t, (err == nil) != (plan == nil), \"PlanEvent should return either a plan or an error\")\n\t\tif err == nil && plan != nil {\n\t\t\terr = runner.NewPlanExecutor(plan)(ctx)\n\t\t\tif j.errorMessage == \"\" {\n\t\t\t\tassert.Nil(t, err, fullWorkflowPath)\n\t\t\t} else {\n\t\t\t\tassert.Error(t, err, j.errorMessage)\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Println(\"::endgroup::\")\n}\n\ntype TestConfig struct {\n\tLocalRepositories map[string]string `yaml:\"local-repositories\"`\n}\n\nfunc TestRunEvent(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\tctx := context.Background()\n\n\ttables := []TestJobFileInfo{\n\t\t// Shells\n\t\t{workdir, \"shells/defaults\", \"push\", \"\", platforms, secrets},\n\t\t// TODO: figure out why it fails\n\t\t// {workdir, \"shells/custom\", \"push\", \"\", map[string]string{\"ubuntu-latest\": \"catthehacker/ubuntu:pwsh-latest\"}, }, // custom image with pwsh\n\t\t{workdir, \"shells/pwsh\", \"push\", \"\", map[string]string{\"ubuntu-latest\": \"catthehacker/ubuntu:pwsh-latest\"}, secrets}, // custom image with pwsh\n\t\t{workdir, \"shells/bash\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"shells/python\", \"push\", \"\", map[string]string{\"ubuntu-latest\": \"node:16-buster\"}, secrets}, // slim doesn't have python\n\t\t{workdir, \"shells/sh\", \"push\", \"\", platforms, secrets},\n\n\t\t// Local action\n\t\t{workdir, \"local-action-docker-url\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"local-action-dockerfile\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"local-action-via-composite-dockerfile\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"local-action-js\", \"push\", \"\", platforms, secrets},\n\n\t\t// Uses\n\t\t{workdir, \"uses-composite\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-composite-with-error\", \"push\", \"Job 'failing-composite-action' failed\", platforms, secrets},\n\t\t{workdir, \"uses-composite-check-for-input-collision\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-composite-check-for-input-shadowing\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-nested-composite\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"remote-action-composite-js-pre-with-defaults\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"remote-action-composite-action-ref\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-workflow\", \"push\", \"\", platforms, map[string]string{\"secret\": \"keep_it_private\"}},\n\t\t{workdir, \"uses-workflow\", \"pull_request\", \"\", platforms, map[string]string{\"secret\": \"keep_it_private\"}},\n\t\t{workdir, \"uses-docker-url\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"act-composite-env-test\", \"push\", \"\", platforms, secrets},\n\n\t\t// Eval\n\t\t{workdir, \"evalmatrix\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"evalmatrixneeds\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"evalmatrixneeds2\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"evalmatrix-merge-map\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"evalmatrix-merge-array\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"issue-1195\", \"push\", \"\", platforms, secrets},\n\n\t\t{workdir, \"basic\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"fail\", \"push\", \"exit with `FAILURE`: 1\", platforms, secrets},\n\t\t{workdir, \"runs-on\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"checkout\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"job-container\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"job-container-non-root\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"job-container-invalid-credentials\", \"push\", \"failed to handle credentials: failed to interpolate container.credentials.password\", platforms, secrets},\n\t\t{workdir, \"container-hostname\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"remote-action-docker\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"remote-action-docker-new-cache\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"remote-action-js\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"remote-action-js-node-user\", \"push\", \"\", platforms, secrets}, // Test if this works with non root container\n\t\t{workdir, \"matrix\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"matrix-include-exclude\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"matrix-exitcode\", \"push\", \"Job 'test' failed\", platforms, secrets},\n\t\t{workdir, \"commands\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"workdir\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"defaults-run\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"composite-fail-with-output\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"issue-597\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"issue-598\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"if-env-act\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"env-and-path\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"environment-files\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"GITHUB_STATE\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"environment-files-parser-bug\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"non-existent-action\", \"push\", \"Job 'nopanic' failed\", platforms, secrets},\n\t\t{workdir, \"outputs\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"networking\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"steps-context/conclusion\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"steps-context/outcome\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"job-status-check\", \"push\", \"job 'fail' failed\", platforms, secrets},\n\t\t{workdir, \"if-expressions\", \"push\", \"Job 'mytest' failed\", platforms, secrets},\n\t\t{workdir, \"actions-environment-and-context-tests\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-action-with-pre-and-post-step\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"evalenv\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"docker-action-custom-path\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"GITHUB_ENV-use-in-env-ctx\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"ensure-post-steps\", \"push\", \"Job 'second-post-step-should-fail' failed\", platforms, secrets},\n\t\t{workdir, \"workflow_call_inputs\", \"workflow_call\", \"\", platforms, secrets},\n\t\t{workdir, \"workflow_dispatch\", \"workflow_dispatch\", \"\", platforms, secrets},\n\t\t{workdir, \"workflow_dispatch_no_inputs_mapping\", \"workflow_dispatch\", \"\", platforms, secrets},\n\t\t{workdir, \"workflow_dispatch-scalar\", \"workflow_dispatch\", \"\", platforms, secrets},\n\t\t{workdir, \"workflow_dispatch-scalar-composite-action\", \"workflow_dispatch\", \"\", platforms, secrets},\n\t\t{workdir, \"uses-workflow-defaults\", \"workflow_dispatch\", \"\", platforms, secrets},\n\t\t{workdir, \"job-needs-context-contains-result\", \"push\", \"\", platforms, secrets},\n\t\t{\"../model/testdata\", \"strategy\", \"push\", \"\", platforms, secrets}, // TODO: move all testdata into pkg so we can validate it with planner and runner\n\t\t{\"../model/testdata\", \"container-volumes\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"path-handling\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"do-not-leak-step-env-in-composite\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"set-env-step-env-override\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"set-env-new-env-file-per-step\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"no-panic-on-invalid-composite-action\", \"push\", \"jobs failed due to invalid action\", platforms, secrets},\n\t\t// GITHUB_STEP_SUMMARY\n\t\t{workdir, \"stepsummary\", \"push\", \"\", platforms, secrets},\n\n\t\t// services\n\t\t{workdir, \"services\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"services-empty-image\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"services-host-network\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"services-with-container\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"mysql-service-container-with-health-check\", \"push\", \"\", platforms, secrets},\n\n\t\t// local remote action overrides\n\t\t{workdir, \"local-remote-action-overrides\", \"push\", \"\", platforms, secrets},\n\n\t\t// docker action on host executor\n\t\t{workdir, \"docker-action-host-env\", \"push\", \"\", platforms, secrets},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.workflowPath, func(t *testing.T) {\n\t\t\tconfig := &Config{\n\t\t\t\tSecrets: table.secrets,\n\t\t\t}\n\n\t\t\teventFile := filepath.Join(workdir, table.workflowPath, \"event.json\")\n\t\t\tif _, err := os.Stat(eventFile); err == nil {\n\t\t\t\tconfig.EventPath = eventFile\n\t\t\t}\n\n\t\t\ttestConfigFile := filepath.Join(workdir, table.workflowPath, \"config/config.yml\")\n\t\t\tif file, err := os.ReadFile(testConfigFile); err == nil {\n\t\t\t\ttestConfig := &TestConfig{}\n\t\t\t\tif yaml.Unmarshal(file, testConfig) == nil {\n\t\t\t\t\tif testConfig.LocalRepositories != nil {\n\t\t\t\t\t\tconfig.ActionCache = &LocalRepositoryCache{\n\t\t\t\t\t\t\tParent: GoGitActionCache{\n\t\t\t\t\t\t\t\tpath.Clean(path.Join(workdir, \"cache\")),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tLocalRepositories: testConfig.LocalRepositories,\n\t\t\t\t\t\t\tCacheDirCache:     map[string]string{},\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttable.runTest(ctx, t, config)\n\t\t})\n\t}\n}\n\ntype captureJobLoggerFactory struct {\n\tbuffer bytes.Buffer\n}\n\nfunc (factory *captureJobLoggerFactory) WithJobLogger() *logrus.Logger {\n\tlogger := logrus.New()\n\tlogger.SetOutput(&factory.buffer)\n\tlogger.SetLevel(log.TraceLevel)\n\tlogger.SetFormatter(&log.JSONFormatter{})\n\treturn logger\n}\n\nfunc TestPullAndPostStepFailureIsJobFailure(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\tdefCache := &GoGitActionCache{\n\t\tpath.Clean(path.Join(workdir, \"cache\")),\n\t}\n\n\tmockCache := &mockCache{}\n\n\ttables := []struct {\n\t\tTestJobFileInfo\n\t\tActionCache ActionCache\n\t\tSetupResult string\n\t}{\n\t\t{TestJobFileInfo{workdir, \"checkout\", \"push\", \"pull failure\", map[string]string{\"ubuntu-latest\": \"localhost:0000/missing:latest\"}, secrets}, defCache, \"failure\"},\n\t\t{TestJobFileInfo{workdir, \"post-step-failure-is-job-failure\", \"push\", \"post failure\", map[string]string{\"ubuntu-latest\": \"-self-hosted\"}, secrets}, mockCache, \"success\"},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.workflowPath, func(t *testing.T) {\n\t\t\tfactory := &captureJobLoggerFactory{}\n\n\t\t\tconfig := &Config{\n\t\t\t\tSecrets: table.secrets,\n\t\t\t}\n\n\t\t\teventFile := filepath.Join(workdir, table.workflowPath, \"event.json\")\n\t\t\tif _, err := os.Stat(eventFile); err == nil {\n\t\t\t\tconfig.EventPath = eventFile\n\t\t\t}\n\t\t\tconfig.ActionCache = table.ActionCache\n\n\t\t\tlogger := logrus.New()\n\t\t\tlogger.SetOutput(&factory.buffer)\n\t\t\tlogger.SetLevel(log.TraceLevel)\n\t\t\tlogger.SetFormatter(&log.JSONFormatter{})\n\n\t\t\ttable.runTest(common.WithLogger(WithJobLoggerFactory(t.Context(), factory), logger), t, config)\n\t\t\tscan := bufio.NewScanner(&factory.buffer)\n\t\t\tvar hasJobResult, hasStepResult bool\n\t\t\tfor scan.Scan() {\n\t\t\t\tt.Log(scan.Text())\n\t\t\t\tentry := map[string]interface{}{}\n\t\t\t\tif json.Unmarshal(scan.Bytes(), &entry) == nil {\n\t\t\t\t\tif val, ok := entry[\"jobResult\"]; ok {\n\t\t\t\t\t\tassert.Equal(t, \"failure\", val)\n\t\t\t\t\t\thasJobResult = true\n\t\t\t\t\t}\n\t\t\t\t\tif val, ok := entry[\"stepResult\"]; ok && !hasStepResult {\n\t\t\t\t\t\tassert.Equal(t, table.SetupResult, val)\n\t\t\t\t\t\thasStepResult = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert.True(t, hasStepResult, \"stepResult not found\")\n\t\t\tassert.True(t, hasJobResult, \"jobResult not found\")\n\t\t})\n\t}\n}\n\ntype mockCache struct {\n}\n\nfunc (c mockCache) Fetch(ctx context.Context, cacheDir string, url string, ref string, token string) (string, error) {\n\t_ = ctx\n\t_ = cacheDir\n\t_ = url\n\t_ = ref\n\t_ = token\n\treturn \"\", fmt.Errorf(\"fetch failure\")\n}\nfunc (c mockCache) GetTarArchive(ctx context.Context, cacheDir string, sha string, includePrefix string) (io.ReadCloser, error) {\n\t_ = ctx\n\t_ = cacheDir\n\t_ = sha\n\t_ = includePrefix\n\treturn nil, fmt.Errorf(\"fetch failure\")\n}\n\nfunc TestFetchFailureIsJobFailure(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\ttables := []TestJobFileInfo{\n\t\t{workdir, \"action-cache-v2-fetch-failure-is-job-error\", \"push\", \"fetch failure\", map[string]string{\"ubuntu-latest\": \"-self-hosted\"}, secrets},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.workflowPath, func(t *testing.T) {\n\t\t\tfactory := &captureJobLoggerFactory{}\n\n\t\t\tconfig := &Config{\n\t\t\t\tSecrets: table.secrets,\n\t\t\t}\n\n\t\t\teventFile := filepath.Join(workdir, table.workflowPath, \"event.json\")\n\t\t\tif _, err := os.Stat(eventFile); err == nil {\n\t\t\t\tconfig.EventPath = eventFile\n\t\t\t}\n\t\t\tconfig.ActionCache = &mockCache{}\n\n\t\t\tlogger := logrus.New()\n\t\t\tlogger.SetOutput(&factory.buffer)\n\t\t\tlogger.SetLevel(log.TraceLevel)\n\t\t\tlogger.SetFormatter(&log.JSONFormatter{})\n\n\t\t\ttable.runTest(common.WithLogger(WithJobLoggerFactory(t.Context(), factory), logger), t, config)\n\t\t\tscan := bufio.NewScanner(&factory.buffer)\n\t\t\tvar hasJobResult bool\n\t\t\tfor scan.Scan() {\n\t\t\t\tt.Log(scan.Text())\n\t\t\t\tentry := map[string]interface{}{}\n\t\t\t\tif json.Unmarshal(scan.Bytes(), &entry) == nil {\n\t\t\t\t\tif val, ok := entry[\"jobResult\"]; ok {\n\t\t\t\t\t\tassert.Equal(t, \"failure\", val)\n\t\t\t\t\t\thasJobResult = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert.True(t, hasJobResult, \"jobResult not found\")\n\t\t})\n\t}\n}\n\nfunc TestRunEventHostEnvironment(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\tctx := context.Background()\n\n\ttables := []TestJobFileInfo{}\n\n\tif runtime.GOOS == \"linux\" {\n\t\tplatforms := map[string]string{\n\t\t\t\"ubuntu-latest\": \"-self-hosted\",\n\t\t}\n\n\t\ttables = append(tables, []TestJobFileInfo{\n\t\t\t// Shells\n\t\t\t{workdir, \"shells/defaults\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"shells/pwsh\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"shells/bash\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"shells/python\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"shells/sh\", \"push\", \"\", platforms, secrets},\n\n\t\t\t// Local action\n\t\t\t{workdir, \"local-action-js\", \"push\", \"\", platforms, secrets},\n\n\t\t\t// Uses\n\t\t\t{workdir, \"uses-composite\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"uses-composite-with-error\", \"push\", \"Job 'failing-composite-action' failed\", platforms, secrets},\n\t\t\t{workdir, \"uses-nested-composite\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"act-composite-env-test\", \"push\", \"\", platforms, secrets},\n\n\t\t\t// Eval\n\t\t\t{workdir, \"evalmatrix\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"evalmatrixneeds\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"evalmatrixneeds2\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"evalmatrix-merge-map\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"evalmatrix-merge-array\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"issue-1195\", \"push\", \"\", platforms, secrets},\n\n\t\t\t{workdir, \"fail\", \"push\", \"exit with `FAILURE`: 1\", platforms, secrets},\n\t\t\t{workdir, \"runs-on\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"checkout\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"remote-action-js\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"matrix\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"matrix-include-exclude\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"commands\", \"push\", \"\", platforms, secrets},\n\t\t\t// Disabled for now because this test is somewhat invalid\n\t\t\t// shell sh is not necessarily bash if the job has no override\n\t\t\t// {workdir, \"defaults-run\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"composite-fail-with-output\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"issue-597\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"issue-598\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"if-env-act\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"env-and-path\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"non-existent-action\", \"push\", \"Job 'nopanic' failed\", platforms, secrets},\n\t\t\t{workdir, \"outputs\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"steps-context/conclusion\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"steps-context/outcome\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"job-status-check\", \"push\", \"job 'fail' failed\", platforms, secrets},\n\t\t\t{workdir, \"if-expressions\", \"push\", \"Job 'mytest' failed\", platforms, secrets},\n\t\t\t{workdir, \"uses-action-with-pre-and-post-step\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"evalenv\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"ensure-post-steps\", \"push\", \"Job 'second-post-step-should-fail' failed\", platforms, secrets},\n\t\t}...)\n\t}\n\tif runtime.GOOS == \"windows\" {\n\t\tplatforms := map[string]string{\n\t\t\t\"windows-latest\": \"-self-hosted\",\n\t\t}\n\n\t\ttables = append(tables, []TestJobFileInfo{\n\t\t\t{workdir, \"windows-prepend-path\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"windows-add-env\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"windows-prepend-path-powershell-5\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"windows-add-env-powershell-5\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"windows-shell-cmd\", \"push\", \"\", platforms, secrets},\n\t\t}...)\n\t} else {\n\t\tplatforms := map[string]string{\n\t\t\t\"self-hosted\":   \"-self-hosted\",\n\t\t\t\"ubuntu-latest\": \"-self-hosted\",\n\t\t}\n\n\t\ttables = append(tables, []TestJobFileInfo{\n\t\t\t{workdir, \"nix-prepend-path\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"inputs-via-env-context\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"do-not-leak-step-env-in-composite\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"set-env-step-env-override\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"set-env-new-env-file-per-step\", \"push\", \"\", platforms, secrets},\n\t\t\t{workdir, \"no-panic-on-invalid-composite-action\", \"push\", \"jobs failed due to invalid action\", platforms, secrets},\n\t\t}...)\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.workflowPath, func(t *testing.T) {\n\t\t\ttable.runTest(ctx, t, &Config{})\n\t\t})\n\t}\n}\n\nfunc TestDryrunEvent(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\tctx := common.WithDryrun(context.Background(), true)\n\n\ttables := []TestJobFileInfo{\n\t\t// Shells\n\t\t{workdir, \"shells/defaults\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"shells/pwsh\", \"push\", \"\", map[string]string{\"ubuntu-latest\": \"catthehacker/ubuntu:pwsh-latest\"}, secrets}, // custom image with pwsh\n\t\t{workdir, \"shells/bash\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"shells/python\", \"push\", \"\", map[string]string{\"ubuntu-latest\": \"node:16-buster\"}, secrets}, // slim doesn't have python\n\t\t{workdir, \"shells/sh\", \"push\", \"\", platforms, secrets},\n\n\t\t// Local action\n\t\t{workdir, \"local-action-docker-url\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"local-action-dockerfile\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"local-action-via-composite-dockerfile\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"local-action-js\", \"push\", \"\", platforms, secrets},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.workflowPath, func(t *testing.T) {\n\t\t\ttable.runTest(ctx, t, &Config{})\n\t\t})\n\t}\n}\n\nfunc TestDockerActionForcePullForceRebuild(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\tctx := context.Background()\n\n\tconfig := &Config{\n\t\tForcePull:    true,\n\t\tForceRebuild: true,\n\t}\n\n\ttables := []TestJobFileInfo{\n\t\t{workdir, \"local-action-dockerfile\", \"push\", \"\", platforms, secrets},\n\t\t{workdir, \"local-action-via-composite-dockerfile\", \"push\", \"\", platforms, secrets},\n\t}\n\n\tfor _, table := range tables {\n\t\tt.Run(table.workflowPath, func(t *testing.T) {\n\t\t\ttable.runTest(ctx, t, config)\n\t\t})\n\t}\n}\n\nfunc TestRunDifferentArchitecture(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\ttjfi := TestJobFileInfo{\n\t\tworkdir:      workdir,\n\t\tworkflowPath: \"basic\",\n\t\teventName:    \"push\",\n\t\terrorMessage: \"\",\n\t\tplatforms:    platforms,\n\t}\n\n\ttjfi.runTest(context.Background(), t, &Config{ContainerArchitecture: \"linux/arm64\"})\n}\n\ntype maskJobLoggerFactory struct {\n\tOutput bytes.Buffer\n}\n\nfunc (f *maskJobLoggerFactory) WithJobLogger() *log.Logger {\n\tlogger := log.New()\n\tlogger.SetOutput(io.MultiWriter(&f.Output, os.Stdout))\n\tlogger.SetLevel(log.DebugLevel)\n\treturn logger\n}\n\nfunc TestMaskValues(t *testing.T) {\n\tassertNoSecret := func(text string, _ string) {\n\t\tindex := strings.Index(text, \"composite secret\")\n\t\tif index > -1 {\n\t\t\tfmt.Printf(\"\\nFound Secret in the given text:\\n%s\\n\", text)\n\t\t}\n\t\tassert.False(t, strings.Contains(text, \"composite secret\"))\n\t}\n\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\tlog.SetLevel(log.DebugLevel)\n\n\ttjfi := TestJobFileInfo{\n\t\tworkdir:      workdir,\n\t\tworkflowPath: \"mask-values\",\n\t\teventName:    \"push\",\n\t\terrorMessage: \"\",\n\t\tplatforms:    platforms,\n\t}\n\n\tlogger := &maskJobLoggerFactory{}\n\ttjfi.runTest(WithJobLoggerFactory(common.WithLogger(context.Background(), logger.WithJobLogger()), logger), t, &Config{})\n\toutput := logger.Output.String()\n\n\tassertNoSecret(output, \"secret value\")\n\tassertNoSecret(output, \"YWJjCg==\")\n}\n\nfunc TestRunEventSecrets(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\tworkflowPath := \"secrets\"\n\n\ttjfi := TestJobFileInfo{\n\t\tworkdir:      workdir,\n\t\tworkflowPath: workflowPath,\n\t\teventName:    \"push\",\n\t\terrorMessage: \"\",\n\t\tplatforms:    platforms,\n\t}\n\n\tenv, err := godotenv.Read(filepath.Join(workdir, workflowPath, \".env\"))\n\tassert.NoError(t, err, \"Failed to read .env\")\n\tsecrets, _ := godotenv.Read(filepath.Join(workdir, workflowPath, \".secrets\"))\n\tassert.NoError(t, err, \"Failed to read .secrets\")\n\n\ttjfi.runTest(context.Background(), t, &Config{Secrets: secrets, Env: env})\n}\n\nfunc TestRunActionInputs(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\tworkflowPath := \"input-from-cli\"\n\n\ttjfi := TestJobFileInfo{\n\t\tworkdir:      workdir,\n\t\tworkflowPath: workflowPath,\n\t\teventName:    \"workflow_dispatch\",\n\t\terrorMessage: \"\",\n\t\tplatforms:    platforms,\n\t}\n\n\tinputs := map[string]string{\n\t\t\"SOME_INPUT\": \"input\",\n\t}\n\n\ttjfi.runTest(context.Background(), t, &Config{Inputs: inputs})\n}\n\nfunc TestRunEventPullRequest(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\n\tworkflowPath := \"pull-request\"\n\n\ttjfi := TestJobFileInfo{\n\t\tworkdir:      workdir,\n\t\tworkflowPath: workflowPath,\n\t\teventName:    \"pull_request\",\n\t\terrorMessage: \"\",\n\t\tplatforms:    platforms,\n\t}\n\n\ttjfi.runTest(context.Background(), t, &Config{EventPath: filepath.Join(workdir, workflowPath, \"event.json\")})\n}\n\nfunc TestRunMatrixWithUserDefinedInclusions(t *testing.T) {\n\tif testing.Short() {\n\t\tt.Skip(\"skipping integration test\")\n\t}\n\tworkflowPath := \"matrix-with-user-inclusions\"\n\n\ttjfi := TestJobFileInfo{\n\t\tworkdir:      workdir,\n\t\tworkflowPath: workflowPath,\n\t\teventName:    \"push\",\n\t\terrorMessage: \"\",\n\t\tplatforms:    platforms,\n\t}\n\n\tmatrix := map[string]map[string]bool{\n\t\t\"node\": {\n\t\t\t\"8\":   true,\n\t\t\t\"8.x\": true,\n\t\t},\n\t\t\"os\": {\n\t\t\t\"ubuntu-18.04\": true,\n\t\t},\n\t}\n\n\ttjfi.runTest(context.Background(), t, &Config{Matrix: matrix})\n}\n"
  },
  {
    "path": "pkg/runner/step.go",
    "content": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/exprparser\"\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/sirupsen/logrus\"\n)\n\ntype step interface {\n\tpre() common.Executor\n\tmain() common.Executor\n\tpost() common.Executor\n\n\tgetRunContext() *RunContext\n\tgetGithubContext(ctx context.Context) *model.GithubContext\n\tgetStepModel() *model.Step\n\tgetEnv() *map[string]string\n\tgetIfExpression(context context.Context, stage stepStage) string\n}\n\ntype stepStage int\n\nconst (\n\tstepStagePre stepStage = iota\n\tstepStageMain\n\tstepStagePost\n)\n\n// Controls how many symlinks are resolved for local and remote Actions\nconst maxSymlinkDepth = 10\n\nfunc (s stepStage) String() string {\n\tswitch s {\n\tcase stepStagePre:\n\t\treturn \"Pre\"\n\tcase stepStageMain:\n\t\treturn \"Main\"\n\tcase stepStagePost:\n\t\treturn \"Post\"\n\t}\n\treturn \"Unknown\"\n}\n\nfunc processRunnerSummaryCommand(ctx context.Context, fileName string, rc *RunContext) error {\n\tif common.Dryrun(ctx) {\n\t\treturn nil\n\t}\n\tpathTar, err := rc.JobContainer.GetContainerArchive(ctx, path.Join(rc.JobContainer.GetActPath(), fileName))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer pathTar.Close()\n\n\treader := tar.NewReader(pathTar)\n\t_, err = reader.Next()\n\tif err != nil && err != io.EOF {\n\t\treturn err\n\t}\n\tsummary, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(summary) == 0 {\n\t\treturn nil\n\t}\n\tcommon.Logger(ctx).WithFields(logrus.Fields{\"command\": \"summary\", \"content\": string(summary)}).Infof(\"  \\U00002699  Summary - %s\", string(summary))\n\treturn nil\n}\n\nfunc processRunnerEnvFileCommand(ctx context.Context, fileName string, rc *RunContext, setter func(context.Context, map[string]string, string)) error {\n\tenv := map[string]string{}\n\terr := rc.JobContainer.UpdateFromEnv(path.Join(rc.JobContainer.GetActPath(), fileName), &env)(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor k, v := range env {\n\t\tsetter(ctx, map[string]string{\"name\": k}, v)\n\t}\n\treturn nil\n}\n\nfunc runStepExecutor(step step, stage stepStage, executor common.Executor) common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\trc := step.getRunContext()\n\t\tstepModel := step.getStepModel()\n\n\t\tifExpression := step.getIfExpression(ctx, stage)\n\t\trc.CurrentStep = stepModel.ID\n\n\t\tstepResult := &model.StepResult{\n\t\t\tOutcome:    model.StepStatusSuccess,\n\t\t\tConclusion: model.StepStatusSuccess,\n\t\t\tOutputs:    make(map[string]string),\n\t\t}\n\t\tif stage == stepStageMain {\n\t\t\trc.StepResults[rc.CurrentStep] = stepResult\n\t\t}\n\n\t\terr := setupEnv(ctx, step)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcctx := common.JobCancelContext(ctx)\n\t\trc.Cancelled = cctx != nil && cctx.Err() != nil\n\n\t\trunStep, err := isStepEnabled(ctx, ifExpression, step, stage)\n\t\tif err != nil {\n\t\t\tstepResult.Conclusion = model.StepStatusFailure\n\t\t\tstepResult.Outcome = model.StepStatusFailure\n\t\t\treturn err\n\t\t}\n\n\t\tif !runStep {\n\t\t\tstepResult.Conclusion = model.StepStatusSkipped\n\t\t\tstepResult.Outcome = model.StepStatusSkipped\n\t\t\tlogger.WithField(\"stepResult\", stepResult.Outcome).Debugf(\"Skipping step '%s' due to '%s'\", stepModel, ifExpression)\n\t\t\treturn nil\n\t\t}\n\n\t\tstepString := rc.ExprEval.Interpolate(ctx, stepModel.String())\n\t\tif strings.Contains(stepString, \"::add-mask::\") {\n\t\t\tstepString = \"add-mask command\"\n\t\t}\n\t\tlogger.Infof(\"\\u2B50 Run %s %s\", stage, stepString)\n\n\t\t// Prepare and clean Runner File Commands\n\t\tactPath := rc.JobContainer.GetActPath()\n\n\t\toutputFileCommand := path.Join(\"workflow\", \"outputcmd.txt\")\n\t\t(*step.getEnv())[\"GITHUB_OUTPUT\"] = path.Join(actPath, outputFileCommand)\n\n\t\tstateFileCommand := path.Join(\"workflow\", \"statecmd.txt\")\n\t\t(*step.getEnv())[\"GITHUB_STATE\"] = path.Join(actPath, stateFileCommand)\n\n\t\tpathFileCommand := path.Join(\"workflow\", \"pathcmd.txt\")\n\t\t(*step.getEnv())[\"GITHUB_PATH\"] = path.Join(actPath, pathFileCommand)\n\n\t\tenvFileCommand := path.Join(\"workflow\", \"envs.txt\")\n\t\t(*step.getEnv())[\"GITHUB_ENV\"] = path.Join(actPath, envFileCommand)\n\n\t\tsummaryFileCommand := path.Join(\"workflow\", \"SUMMARY.md\")\n\t\t(*step.getEnv())[\"GITHUB_STEP_SUMMARY\"] = path.Join(actPath, summaryFileCommand)\n\n\t\t_ = rc.JobContainer.Copy(actPath, &container.FileEntry{\n\t\t\tName: outputFileCommand,\n\t\t\tMode: 0o666,\n\t\t}, &container.FileEntry{\n\t\t\tName: stateFileCommand,\n\t\t\tMode: 0o666,\n\t\t}, &container.FileEntry{\n\t\t\tName: pathFileCommand,\n\t\t\tMode: 0o666,\n\t\t}, &container.FileEntry{\n\t\t\tName: envFileCommand,\n\t\t\tMode: 0666,\n\t\t}, &container.FileEntry{\n\t\t\tName: summaryFileCommand,\n\t\t\tMode: 0o666,\n\t\t})(ctx)\n\n\t\tstepCtx, cancelStepCtx := context.WithCancel(ctx)\n\t\tdefer cancelStepCtx()\n\t\tvar cancelTimeOut context.CancelFunc\n\t\tstepCtx, cancelTimeOut = evaluateStepTimeout(stepCtx, rc.ExprEval, stepModel)\n\t\tdefer cancelTimeOut()\n\t\tmonitorJobCancellation(ctx, stepCtx, cctx, rc, logger, ifExpression, step, stage, cancelStepCtx)\n\t\tstartTime := time.Now()\n\t\terr = executor(stepCtx)\n\t\texecutionTime := time.Since(startTime)\n\n\t\tif err == nil {\n\t\t\tlogger.WithFields(logrus.Fields{\"executionTime\": executionTime, \"stepResult\": stepResult.Outcome}).Infof(\"  \\u2705  Success - %s %s [%s]\", stage, stepString, executionTime)\n\t\t} else {\n\t\t\tstepResult.Outcome = model.StepStatusFailure\n\n\t\t\tcontinueOnError, parseErr := isContinueOnError(ctx, stepModel.RawContinueOnError, step, stage)\n\t\t\tif parseErr != nil {\n\t\t\t\tstepResult.Conclusion = model.StepStatusFailure\n\t\t\t\treturn parseErr\n\t\t\t}\n\n\t\t\tif continueOnError {\n\t\t\t\tlogger.Infof(\"Failed but continue next step\")\n\t\t\t\terr = nil\n\t\t\t\tstepResult.Conclusion = model.StepStatusSuccess\n\t\t\t} else {\n\t\t\t\tstepResult.Conclusion = model.StepStatusFailure\n\t\t\t}\n\n\t\t\tlogger.WithFields(logrus.Fields{\"executionTime\": executionTime, \"stepResult\": stepResult.Outcome}).Infof(\"  \\u274C  Failure - %s %s [%s]\", stage, stepString, executionTime)\n\t\t}\n\t\t// Process Runner File Commands\n\t\tferrors := []error{err}\n\t\tferrors = append(ferrors, processRunnerEnvFileCommand(ctx, envFileCommand, rc, rc.setEnv))\n\t\tferrors = append(ferrors, processRunnerEnvFileCommand(ctx, stateFileCommand, rc, rc.saveState))\n\t\tferrors = append(ferrors, processRunnerEnvFileCommand(ctx, outputFileCommand, rc, rc.setOutput))\n\t\tferrors = append(ferrors, processRunnerSummaryCommand(ctx, summaryFileCommand, rc))\n\t\tferrors = append(ferrors, rc.UpdateExtraPath(ctx, path.Join(actPath, pathFileCommand)))\n\t\treturn errors.Join(ferrors...)\n\t}\n}\n\nfunc monitorJobCancellation(ctx context.Context, stepCtx context.Context, jobCancellationCtx context.Context, rc *RunContext, logger logrus.FieldLogger, ifExpression string, step step, stage stepStage, cancelStepCtx context.CancelFunc) {\n\tif !rc.Cancelled && jobCancellationCtx != nil {\n\t\tgo func() {\n\t\t\tselect {\n\t\t\tcase <-jobCancellationCtx.Done():\n\t\t\t\trc.Cancelled = true\n\t\t\t\tlogger.Infof(\"Reevaluate condition %v due to cancellation\", ifExpression)\n\t\t\t\tkeepStepRunning, err := isStepEnabled(ctx, ifExpression, step, stage)\n\t\t\t\tlogger.Infof(\"Result condition keepStepRunning=%v\", keepStepRunning)\n\t\t\t\tif !keepStepRunning || err != nil {\n\t\t\t\t\tcancelStepCtx()\n\t\t\t\t}\n\t\t\tcase <-stepCtx.Done():\n\t\t\t}\n\t\t}()\n\t}\n}\n\nfunc evaluateStepTimeout(ctx context.Context, exprEval ExpressionEvaluator, stepModel *model.Step) (context.Context, context.CancelFunc) {\n\ttimeout := exprEval.Interpolate(ctx, stepModel.TimeoutMinutes)\n\tif timeout != \"\" {\n\t\tif timeOutMinutes, err := strconv.ParseInt(timeout, 10, 64); err == nil {\n\t\t\treturn context.WithTimeout(ctx, time.Duration(timeOutMinutes)*time.Minute)\n\t\t}\n\t}\n\treturn ctx, func() {}\n}\n\nfunc setupEnv(ctx context.Context, step step) error {\n\trc := step.getRunContext()\n\n\tmergeEnv(ctx, step)\n\t// merge step env last, since it should not be overwritten\n\tmergeIntoMap(step, step.getEnv(), step.getStepModel().GetEnv())\n\n\texprEval := rc.NewExpressionEvaluator(ctx)\n\tfor k, v := range *step.getEnv() {\n\t\tif !strings.HasPrefix(k, \"INPUT_\") {\n\t\t\t(*step.getEnv())[k] = exprEval.Interpolate(ctx, v)\n\t\t}\n\t}\n\t// after we have an evaluated step context, update the expressions evaluator with a new env context\n\t// you can use step level env in the with property of a uses construct\n\texprEval = rc.NewExpressionEvaluatorWithEnv(ctx, *step.getEnv())\n\tfor k, v := range *step.getEnv() {\n\t\tif strings.HasPrefix(k, \"INPUT_\") {\n\t\t\t(*step.getEnv())[k] = exprEval.Interpolate(ctx, v)\n\t\t}\n\t}\n\n\tcommon.Logger(ctx).Debugf(\"setupEnv => %v\", *step.getEnv())\n\n\treturn nil\n}\n\nfunc mergeEnv(ctx context.Context, step step) {\n\tenv := step.getEnv()\n\trc := step.getRunContext()\n\tjob := rc.Run.Job()\n\n\tc := job.Container()\n\tif c != nil {\n\t\tmergeIntoMap(step, env, rc.GetEnv(), c.Env)\n\t} else {\n\t\tmergeIntoMap(step, env, rc.GetEnv())\n\t}\n\n\trc.withGithubEnv(ctx, step.getGithubContext(ctx), *env)\n\n\tif step.getStepModel().Uses != \"\" {\n\t\t// prevent uses action input pollution of unset parameters, skip this for run steps\n\t\t// due to design flaw\n\t\tfor key := range *env {\n\t\t\tif strings.Contains(key, \"INPUT_\") {\n\t\t\t\tdelete(*env, key)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc isStepEnabled(ctx context.Context, expr string, step step, stage stepStage) (bool, error) {\n\trc := step.getRunContext()\n\n\tvar defaultStatusCheck exprparser.DefaultStatusCheck\n\tif stage == stepStagePost {\n\t\tdefaultStatusCheck = exprparser.DefaultStatusCheckAlways\n\t} else {\n\t\tdefaultStatusCheck = exprparser.DefaultStatusCheckSuccess\n\t}\n\n\trunStep, err := EvalBool(ctx, rc.NewStepExpressionEvaluatorExt(ctx, step, stage == stepStageMain), expr, defaultStatusCheck)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"  \\u274C  Error in if-expression: \\\"if: %s\\\" (%s)\", expr, err)\n\t}\n\n\treturn runStep, nil\n}\n\nfunc isContinueOnError(ctx context.Context, expr string, step step, _ stepStage) (bool, error) {\n\t// https://github.com/github/docs/blob/3ae84420bd10997bb5f35f629ebb7160fe776eae/content/actions/reference/workflow-syntax-for-github-actions.md?plain=true#L962\n\tif len(strings.TrimSpace(expr)) == 0 {\n\t\treturn false, nil\n\t}\n\n\trc := step.getRunContext()\n\n\tcontinueOnError, err := EvalBool(ctx, rc.NewStepExpressionEvaluator(ctx, step), expr, exprparser.DefaultStatusCheckNone)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"  \\u274C  Error in continue-on-error-expression: \\\"continue-on-error: %s\\\" (%s)\", expr, err)\n\t}\n\n\treturn continueOnError, nil\n}\n\nfunc mergeIntoMap(step step, target *map[string]string, maps ...map[string]string) {\n\tif rc := step.getRunContext(); rc != nil && rc.JobContainer != nil && rc.JobContainer.IsEnvironmentCaseInsensitive() {\n\t\tmergeIntoMapCaseInsensitive(*target, maps...)\n\t} else {\n\t\tmergeIntoMapCaseSensitive(*target, maps...)\n\t}\n}\n\nfunc mergeIntoMapCaseSensitive(target map[string]string, maps ...map[string]string) {\n\tfor _, m := range maps {\n\t\tfor k, v := range m {\n\t\t\ttarget[k] = v\n\t\t}\n\t}\n}\n\nfunc mergeIntoMapCaseInsensitive(target map[string]string, maps ...map[string]string) {\n\tfoldKeys := make(map[string]string, len(target))\n\tfor k := range target {\n\t\tfoldKeys[strings.ToLower(k)] = k\n\t}\n\ttoKey := func(s string) string {\n\t\tfoldKey := strings.ToLower(s)\n\t\tif k, ok := foldKeys[foldKey]; ok {\n\t\t\treturn k\n\t\t}\n\t\tfoldKeys[strings.ToLower(foldKey)] = s\n\t\treturn s\n\t}\n\tfor _, m := range maps {\n\t\tfor k, v := range m {\n\t\t\ttarget[toKey(k)] = v\n\t\t}\n\t}\n}\n\nfunc symlinkJoin(filename, sym, parent string) (string, error) {\n\tdir := path.Dir(filename)\n\tdest := path.Join(dir, sym)\n\tprefix := path.Clean(parent) + \"/\"\n\tif strings.HasPrefix(dest, prefix) || prefix == \"./\" {\n\t\treturn dest, nil\n\t}\n\treturn \"\", fmt.Errorf(\"symlink tries to access file '%s' outside of '%s'\", strings.ReplaceAll(dest, \"'\", \"''\"), strings.ReplaceAll(parent, \"'\", \"''\"))\n}\n"
  },
  {
    "path": "pkg/runner/step_action_local.go",
    "content": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype stepActionLocal struct {\n\tStep                *model.Step\n\tRunContext          *RunContext\n\tcompositeRunContext *RunContext\n\tcompositeSteps      *compositeSteps\n\trunAction           runAction\n\treadAction          readAction\n\tenv                 map[string]string\n\taction              *model.Action\n}\n\nfunc (sal *stepActionLocal) pre() common.Executor {\n\tsal.env = map[string]string{}\n\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc (sal *stepActionLocal) main() common.Executor {\n\treturn runStepExecutor(sal, stepStageMain, func(ctx context.Context) error {\n\t\tif common.Dryrun(ctx) {\n\t\t\treturn nil\n\t\t}\n\n\t\tactionDir := filepath.Join(sal.getRunContext().Config.Workdir, sal.Step.Uses)\n\n\t\tlocalReader := func(ctx context.Context) actionYamlReader {\n\t\t\t_, cpath := getContainerActionPaths(sal.Step, path.Join(actionDir, \"\"), sal.RunContext)\n\t\t\treturn func(filename string) (io.Reader, io.Closer, error) {\n\t\t\t\tspath := path.Join(cpath, filename)\n\t\t\t\tfor i := 0; i < maxSymlinkDepth; i++ {\n\t\t\t\t\ttars, err := sal.RunContext.JobContainer.GetContainerArchive(ctx, spath)\n\t\t\t\t\tif errors.Is(err, fs.ErrNotExist) {\n\t\t\t\t\t\treturn nil, nil, err\n\t\t\t\t\t} else if err != nil {\n\t\t\t\t\t\treturn nil, nil, fs.ErrNotExist\n\t\t\t\t\t}\n\t\t\t\t\ttreader := tar.NewReader(tars)\n\t\t\t\t\theader, err := treader.Next()\n\t\t\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t\t\treturn nil, nil, os.ErrNotExist\n\t\t\t\t\t} else if err != nil {\n\t\t\t\t\t\treturn nil, nil, err\n\t\t\t\t\t}\n\t\t\t\t\tif header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink {\n\t\t\t\t\t\tspath, err = symlinkJoin(spath, header.Linkname, cpath)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, nil, err\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn treader, tars, nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn nil, nil, fmt.Errorf(\"max depth %d of symlinks exceeded while reading %s\", maxSymlinkDepth, spath)\n\t\t\t}\n\t\t}\n\n\t\tactionModel, err := sal.readAction(ctx, sal.Step, actionDir, \"\", localReader(ctx), os.WriteFile)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsal.action = actionModel\n\n\t\treturn sal.runAction(sal, actionDir, nil)(ctx)\n\t})\n}\n\nfunc (sal *stepActionLocal) post() common.Executor {\n\treturn runStepExecutor(sal, stepStagePost, runPostStep(sal)).If(hasPostStep(sal)).If(shouldRunPostStep(sal))\n}\n\nfunc (sal *stepActionLocal) getRunContext() *RunContext {\n\treturn sal.RunContext\n}\n\nfunc (sal *stepActionLocal) getGithubContext(ctx context.Context) *model.GithubContext {\n\treturn sal.getRunContext().getGithubContext(ctx)\n}\n\nfunc (sal *stepActionLocal) getStepModel() *model.Step {\n\treturn sal.Step\n}\n\nfunc (sal *stepActionLocal) getEnv() *map[string]string {\n\treturn &sal.env\n}\n\nfunc (sal *stepActionLocal) getIfExpression(_ context.Context, stage stepStage) string {\n\tswitch stage {\n\tcase stepStageMain:\n\t\treturn sal.Step.If.Value\n\tcase stepStagePost:\n\t\treturn sal.action.Runs.PostIf\n\t}\n\treturn \"\"\n}\n\nfunc (sal *stepActionLocal) getActionModel() *model.Action {\n\treturn sal.action\n}\n\nfunc (sal *stepActionLocal) getCompositeRunContext(ctx context.Context) *RunContext {\n\tif sal.compositeRunContext == nil {\n\t\tactionDir := filepath.Join(sal.RunContext.Config.Workdir, sal.Step.Uses)\n\t\t_, containerActionDir := getContainerActionPaths(sal.getStepModel(), actionDir, sal.RunContext)\n\n\t\tsal.compositeRunContext = newCompositeRunContext(ctx, sal.RunContext, sal, containerActionDir)\n\t\tsal.compositeSteps = sal.compositeRunContext.compositeExecutor(sal.action)\n\t}\n\treturn sal.compositeRunContext\n}\n\nfunc (sal *stepActionLocal) getCompositeSteps() *compositeSteps {\n\treturn sal.compositeSteps\n}\n"
  },
  {
    "path": "pkg/runner/step_action_local_test.go",
    "content": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"gopkg.in/yaml.v3\"\n)\n\ntype stepActionLocalMocks struct {\n\tmock.Mock\n}\n\nfunc (salm *stepActionLocalMocks) runAction(step actionStep, actionDir string, remoteAction *remoteAction) common.Executor {\n\targs := salm.Called(step, actionDir, remoteAction)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (salm *stepActionLocalMocks) readAction(_ context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {\n\targs := salm.Called(step, actionDir, actionPath, readFile, writeFile)\n\treturn args.Get(0).(*model.Action), args.Error(1)\n}\n\nfunc TestStepActionLocalTest(t *testing.T) {\n\tctx := context.Background()\n\n\tcm := &containerMock{}\n\tsalm := &stepActionLocalMocks{}\n\n\tsal := &stepActionLocal{\n\t\treadAction: salm.readAction,\n\t\trunAction:  salm.runAction,\n\t\tRunContext: &RunContext{\n\t\t\tStepResults: map[string]*model.StepResult{},\n\t\t\tExprEval:    &expressionEvaluator{},\n\t\t\tConfig: &Config{\n\t\t\t\tWorkdir: \"/tmp\",\n\t\t\t},\n\t\t\tRun: &model.Run{\n\t\t\t\tJobID: \"1\",\n\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\"1\": {\n\t\t\t\t\t\t\tDefaults: model.Defaults{\n\t\t\t\t\t\t\t\tRun: model.RunDefaults{\n\t\t\t\t\t\t\t\t\tShell: \"bash\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tJobContainer: cm,\n\t\t},\n\t\tStep: &model.Step{\n\t\t\tID:   \"1\",\n\t\t\tUses: \"./path/to/action\",\n\t\t},\n\t}\n\n\tsalm.On(\"readAction\", sal.Step, filepath.Clean(\"/tmp/path/to/action\"), \"\", mock.Anything, mock.Anything).\n\t\tReturn(&model.Action{}, nil)\n\n\tcm.On(\"Copy\", \"/var/run/act\", mock.AnythingOfType(\"[]*container.FileEntry\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/envs.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/statecmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/outputcmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/SUMMARY.md\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/pathcmd.txt\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\n\tsalm.On(\"runAction\", sal, filepath.Clean(\"/tmp/path/to/action\"), (*remoteAction)(nil)).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\terr := sal.pre()(ctx)\n\tassert.Nil(t, err)\n\n\terr = sal.main()(ctx)\n\tassert.Nil(t, err)\n\n\tcm.AssertExpectations(t)\n\tsalm.AssertExpectations(t)\n}\n\nfunc TestStepActionLocalPost(t *testing.T) {\n\ttable := []struct {\n\t\tname               string\n\t\tstepModel          *model.Step\n\t\tactionModel        *model.Action\n\t\tinitialStepResults map[string]*model.StepResult\n\t\terr                error\n\t\tmocks              struct {\n\t\t\tenv  bool\n\t\t\texec bool\n\t\t}\n\t}{\n\t\t{\n\t\t\tname: \"main-success\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"./local/action\",\n\t\t\t},\n\t\t\tactionModel: &model.Action{\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tPost:   \"post.js\",\n\t\t\t\t\tPostIf: \"always()\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tinitialStepResults: map[string]*model.StepResult{\n\t\t\t\t\"step\": {\n\t\t\t\t\tConclusion: model.StepStatusSuccess,\n\t\t\t\t\tOutcome:    model.StepStatusSuccess,\n\t\t\t\t\tOutputs:    map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv  bool\n\t\t\t\texec bool\n\t\t\t}{\n\t\t\t\tenv:  true,\n\t\t\t\texec: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"main-failed\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"./local/action\",\n\t\t\t},\n\t\t\tactionModel: &model.Action{\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tPost:   \"post.js\",\n\t\t\t\t\tPostIf: \"always()\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tinitialStepResults: map[string]*model.StepResult{\n\t\t\t\t\"step\": {\n\t\t\t\t\tConclusion: model.StepStatusFailure,\n\t\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\t\tOutputs:    map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv  bool\n\t\t\t\texec bool\n\t\t\t}{\n\t\t\t\tenv:  true,\n\t\t\t\texec: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"skip-if-failed\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"./local/action\",\n\t\t\t},\n\t\t\tactionModel: &model.Action{\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tPost:   \"post.js\",\n\t\t\t\t\tPostIf: \"success()\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tinitialStepResults: map[string]*model.StepResult{\n\t\t\t\t\"step\": {\n\t\t\t\t\tConclusion: model.StepStatusFailure,\n\t\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\t\tOutputs:    map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv  bool\n\t\t\t\texec bool\n\t\t\t}{\n\t\t\t\tenv:  false,\n\t\t\t\texec: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"skip-if-main-skipped\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tIf:   yaml.Node{Value: \"failure()\"},\n\t\t\t\tUses: \"./local/action\",\n\t\t\t},\n\t\t\tactionModel: &model.Action{\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tPost:   \"post.js\",\n\t\t\t\t\tPostIf: \"always()\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tinitialStepResults: map[string]*model.StepResult{\n\t\t\t\t\"step\": {\n\t\t\t\t\tConclusion: model.StepStatusSkipped,\n\t\t\t\t\tOutcome:    model.StepStatusSkipped,\n\t\t\t\t\tOutputs:    map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv  bool\n\t\t\t\texec bool\n\t\t\t}{\n\t\t\t\tenv:  false,\n\t\t\t\texec: false,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\n\t\t\tcm := &containerMock{}\n\n\t\t\tsal := &stepActionLocal{\n\t\t\t\tenv: map[string]string{},\n\t\t\t\tRunContext: &RunContext{\n\t\t\t\t\tConfig: &Config{\n\t\t\t\t\t\tGitHubInstance: \"https://github.com\",\n\t\t\t\t\t},\n\t\t\t\t\tJobContainer: cm,\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tJobID: \"1\",\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\t\"1\": {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tStepResults:      tt.initialStepResults,\n\t\t\t\t\tnodeToolFullPath: \"node\",\n\t\t\t\t},\n\t\t\t\tStep:   tt.stepModel,\n\t\t\t\taction: tt.actionModel,\n\t\t\t}\n\t\t\tsal.RunContext.ExprEval = sal.RunContext.NewExpressionEvaluator(ctx)\n\n\t\t\tif tt.mocks.exec {\n\t\t\t\tsuffixMatcher := func(suffix string) interface{} {\n\t\t\t\t\treturn mock.MatchedBy(func(array []string) bool {\n\t\t\t\t\t\treturn strings.HasSuffix(array[1], suffix)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tcm.On(\"Exec\", suffixMatcher(\"pkg/runner/local/action/post.js\"), sal.env, \"\", \"\").Return(func(_ context.Context) error { return tt.err })\n\n\t\t\t\tcm.On(\"Copy\", \"/var/run/act\", mock.AnythingOfType(\"[]*container.FileEntry\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/envs.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/statecmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/outputcmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/SUMMARY.md\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\t\t\t\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/pathcmd.txt\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\t\t\t}\n\n\t\t\terr := sal.post()(ctx)\n\n\t\t\tassert.Equal(t, tt.err, err)\n\t\t\tassert.Equal(t, sal.RunContext.StepResults[\"post-step\"], (*model.StepResult)(nil))\n\t\t\tcm.AssertExpectations(t)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/step_action_remote.go",
    "content": "package runner\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\tgogit \"github.com/go-git/go-git/v5\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/common/git\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype stepActionRemote struct {\n\tStep                *model.Step\n\tRunContext          *RunContext\n\tcompositeRunContext *RunContext\n\tcompositeSteps      *compositeSteps\n\treadAction          readAction\n\trunAction           runAction\n\taction              *model.Action\n\tenv                 map[string]string\n\tremoteAction        *remoteAction\n\tcacheDir            string\n\tresolvedSha         string\n}\n\nvar (\n\tstepActionRemoteNewCloneExecutor = git.NewGitCloneExecutor\n)\n\nfunc (sar *stepActionRemote) prepareActionExecutor() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tif sar.remoteAction != nil && sar.action != nil {\n\t\t\t// we are already good to run\n\t\t\treturn nil\n\t\t}\n\n\t\tsar.remoteAction = newRemoteAction(sar.Step.Uses)\n\t\tif sar.remoteAction == nil {\n\t\t\treturn fmt.Errorf(\"Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format\", sar.Step.Uses)\n\t\t}\n\n\t\tgithub := sar.getGithubContext(ctx)\n\t\tsar.remoteAction.URL = github.ServerURL\n\n\t\tif sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout {\n\t\t\tcommon.Logger(ctx).Debugf(\"Skipping local actions/checkout because workdir was already copied\")\n\t\t\treturn nil\n\t\t}\n\n\t\tfor _, action := range sar.RunContext.Config.ReplaceGheActionWithGithubCom {\n\t\t\tif strings.EqualFold(fmt.Sprintf(\"%s/%s\", sar.remoteAction.Org, sar.remoteAction.Repo), action) {\n\t\t\t\tsar.remoteAction.URL = \"https://github.com\"\n\t\t\t\tgithub.Token = sar.RunContext.Config.ReplaceGheActionTokenWithGithubCom\n\t\t\t}\n\t\t}\n\t\tif sar.RunContext.Config.ActionCache != nil {\n\t\t\tcache := sar.RunContext.Config.ActionCache\n\n\t\t\tvar err error\n\t\t\tsar.cacheDir = fmt.Sprintf(\"%s/%s\", sar.remoteAction.Org, sar.remoteAction.Repo)\n\t\t\trepoURL := sar.remoteAction.URL + \"/\" + sar.cacheDir\n\t\t\trepoRef := sar.remoteAction.Ref\n\t\t\tsar.resolvedSha, err = cache.Fetch(ctx, sar.cacheDir, repoURL, repoRef, github.Token)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to fetch \\\"%s\\\" version \\\"%s\\\": %w\", repoURL, repoRef, err)\n\t\t\t}\n\n\t\t\tremoteReader := func(ctx context.Context) actionYamlReader {\n\t\t\t\treturn func(filename string) (io.Reader, io.Closer, error) {\n\t\t\t\t\tspath := path.Join(sar.remoteAction.Path, filename)\n\t\t\t\t\tfor i := 0; i < maxSymlinkDepth; i++ {\n\t\t\t\t\t\ttars, err := cache.GetTarArchive(ctx, sar.cacheDir, sar.resolvedSha, spath)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, nil, os.ErrNotExist\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttreader := tar.NewReader(tars)\n\t\t\t\t\t\theader, err := treader.Next()\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, nil, os.ErrNotExist\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink {\n\t\t\t\t\t\t\tspath, err = symlinkJoin(spath, header.Linkname, \".\")\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn nil, nil, err\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn treader, tars, nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn nil, nil, fmt.Errorf(\"max depth %d of symlinks exceeded while reading %s\", maxSymlinkDepth, spath)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tactionModel, err := sar.readAction(ctx, sar.Step, sar.resolvedSha, sar.remoteAction.Path, remoteReader(ctx), os.WriteFile)\n\t\t\tsar.action = actionModel\n\t\t\treturn err\n\t\t}\n\n\t\tactionDir := fmt.Sprintf(\"%s/%s\", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses))\n\t\tgitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{\n\t\t\tURL:         sar.remoteAction.CloneURL(),\n\t\t\tRef:         sar.remoteAction.Ref,\n\t\t\tDir:         actionDir,\n\t\t\tToken:       github.Token,\n\t\t\tOfflineMode: sar.RunContext.Config.ActionOfflineMode,\n\t\t})\n\t\tvar ntErr common.Executor\n\t\tif err := gitClone(ctx); err != nil {\n\t\t\tif errors.Is(err, git.ErrShortRef) {\n\t\t\t\treturn fmt.Errorf(\"Unable to resolve action `%s`, the provided ref `%s` is the shortened version of a commit SHA, which is not supported. Please use the full commit SHA `%s` instead\",\n\t\t\t\t\tsar.Step.Uses, sar.remoteAction.Ref, err.(*git.Error).Commit())\n\t\t\t} else if errors.Is(err, gogit.ErrForceNeeded) { // TODO: figure out if it will be easy to shadow/alias go-git err's\n\t\t\t\tntErr = common.NewInfoExecutor(\"Non-terminating error while running 'git clone': %v\", err)\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tremoteReader := func(_ context.Context) actionYamlReader {\n\t\t\treturn func(filename string) (io.Reader, io.Closer, error) {\n\t\t\t\tf, err := os.Open(filepath.Join(actionDir, sar.remoteAction.Path, filename))\n\t\t\t\treturn f, f, err\n\t\t\t}\n\t\t}\n\n\t\treturn common.NewPipelineExecutor(\n\t\t\tntErr,\n\t\t\tfunc(ctx context.Context) error {\n\t\t\t\tactionModel, err := sar.readAction(ctx, sar.Step, actionDir, sar.remoteAction.Path, remoteReader(ctx), os.WriteFile)\n\t\t\t\tsar.action = actionModel\n\t\t\t\treturn err\n\t\t\t},\n\t\t)(ctx)\n\t}\n}\n\nfunc (sar *stepActionRemote) pre() common.Executor {\n\tsar.env = map[string]string{}\n\n\treturn common.NewPipelineExecutor(\n\t\tsar.prepareActionExecutor(),\n\t\trunStepExecutor(sar, stepStagePre, runPreStep(sar)).If(hasPreStep(sar)).If(shouldRunPreStep(sar)))\n}\n\nfunc (sar *stepActionRemote) main() common.Executor {\n\treturn common.NewPipelineExecutor(\n\t\tsar.prepareActionExecutor(),\n\t\trunStepExecutor(sar, stepStageMain, func(ctx context.Context) error {\n\t\t\tgithub := sar.getGithubContext(ctx)\n\t\t\tif sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout {\n\t\t\t\tif sar.RunContext.Config.BindWorkdir {\n\t\t\t\t\tcommon.Logger(ctx).Debugf(\"Skipping local actions/checkout because you bound your workspace\")\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\teval := sar.RunContext.NewExpressionEvaluator(ctx)\n\t\t\t\tcopyToPath := path.Join(sar.RunContext.JobContainer.ToContainerPath(sar.RunContext.Config.Workdir), eval.Interpolate(ctx, sar.Step.With[\"path\"]))\n\t\t\t\treturn sar.RunContext.JobContainer.CopyDir(copyToPath, sar.RunContext.Config.Workdir+string(filepath.Separator)+\".\", sar.RunContext.Config.UseGitIgnore)(ctx)\n\t\t\t}\n\n\t\t\tactionDir := fmt.Sprintf(\"%s/%s\", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses))\n\n\t\t\treturn sar.runAction(sar, actionDir, sar.remoteAction)(ctx)\n\t\t}),\n\t)\n}\n\nfunc (sar *stepActionRemote) post() common.Executor {\n\treturn runStepExecutor(sar, stepStagePost, runPostStep(sar)).If(hasPostStep(sar)).If(shouldRunPostStep(sar))\n}\n\nfunc (sar *stepActionRemote) getRunContext() *RunContext {\n\treturn sar.RunContext\n}\n\nfunc (sar *stepActionRemote) getGithubContext(ctx context.Context) *model.GithubContext {\n\tghc := sar.getRunContext().getGithubContext(ctx)\n\n\t// extend github context if we already have an initialized remoteAction\n\tremoteAction := sar.remoteAction\n\tif remoteAction != nil {\n\t\tghc.ActionRepository = fmt.Sprintf(\"%s/%s\", remoteAction.Org, remoteAction.Repo)\n\t\tghc.ActionRef = remoteAction.Ref\n\t}\n\n\treturn ghc\n}\n\nfunc (sar *stepActionRemote) getStepModel() *model.Step {\n\treturn sar.Step\n}\n\nfunc (sar *stepActionRemote) getEnv() *map[string]string {\n\treturn &sar.env\n}\n\nfunc (sar *stepActionRemote) getIfExpression(ctx context.Context, stage stepStage) string {\n\tswitch stage {\n\tcase stepStagePre:\n\t\tgithub := sar.getGithubContext(ctx)\n\t\tif sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout {\n\t\t\t// skip local checkout pre step\n\t\t\treturn \"false\"\n\t\t}\n\t\treturn sar.action.Runs.PreIf\n\tcase stepStageMain:\n\t\treturn sar.Step.If.Value\n\tcase stepStagePost:\n\t\treturn sar.action.Runs.PostIf\n\t}\n\treturn \"\"\n}\n\nfunc (sar *stepActionRemote) getActionModel() *model.Action {\n\treturn sar.action\n}\n\nfunc (sar *stepActionRemote) getCompositeRunContext(ctx context.Context) *RunContext {\n\tif sar.compositeRunContext == nil {\n\t\tactionDir := fmt.Sprintf(\"%s/%s\", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses))\n\t\tactionLocation := path.Join(actionDir, sar.remoteAction.Path)\n\t\t_, containerActionDir := getContainerActionPaths(sar.getStepModel(), actionLocation, sar.RunContext)\n\n\t\tsar.compositeRunContext = newCompositeRunContext(ctx, sar.RunContext, sar, containerActionDir)\n\t\tsar.compositeSteps = sar.compositeRunContext.compositeExecutor(sar.action)\n\t} else {\n\t\t// Re-evaluate environment here. For remote actions the environment\n\t\t// need to be re-created for every stage (pre, main, post) as there\n\t\t// might be required context changes (inputs/outputs) while the action\n\t\t// stages are executed. (e.g. the output of another action is the\n\t\t// input for this action during the main stage, but the env\n\t\t// was already created during the pre stage)\n\t\tenv := evaluateCompositeInputAndEnv(ctx, sar.RunContext, sar)\n\t\tsar.compositeRunContext.Env = env\n\t\tsar.compositeRunContext.ExtraPath = sar.RunContext.ExtraPath\n\t}\n\treturn sar.compositeRunContext\n}\n\nfunc (sar *stepActionRemote) getCompositeSteps() *compositeSteps {\n\treturn sar.compositeSteps\n}\n\ntype remoteAction struct {\n\tURL  string\n\tOrg  string\n\tRepo string\n\tPath string\n\tRef  string\n}\n\nfunc (ra *remoteAction) CloneURL() string {\n\treturn fmt.Sprintf(\"%s/%s/%s\", ra.URL, ra.Org, ra.Repo)\n}\n\nfunc (ra *remoteAction) IsCheckout() bool {\n\tif ra.Org == \"actions\" && ra.Repo == \"checkout\" {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc newRemoteAction(action string) *remoteAction {\n\t// GitHub's document[^] describes:\n\t// > We strongly recommend that you include the version of\n\t// > the action you are using by specifying a Git ref, SHA, or Docker tag number.\n\t// Actually, the workflow stops if there is the uses directive that hasn't @ref.\n\t// [^]: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions\n\tr := regexp.MustCompile(`^([^/@]+)/([^/@]+)(/([^@]*))?(@(.*))?$`)\n\tmatches := r.FindStringSubmatch(action)\n\tif len(matches) < 7 || matches[6] == \"\" {\n\t\treturn nil\n\t}\n\treturn &remoteAction{\n\t\tOrg:  matches[1],\n\t\tRepo: matches[2],\n\t\tPath: matches[4],\n\t\tRef:  matches[6],\n\t\tURL:  \"https://github.com\",\n\t}\n}\n\nfunc safeFilename(s string) string {\n\treturn strings.NewReplacer(\n\t\t`<`, \"-\",\n\t\t`>`, \"-\",\n\t\t`:`, \"-\",\n\t\t`\"`, \"-\",\n\t\t`/`, \"-\",\n\t\t`\\`, \"-\",\n\t\t`|`, \"-\",\n\t\t`?`, \"-\",\n\t\t`*`, \"-\",\n\t).Replace(s)\n}\n"
  },
  {
    "path": "pkg/runner/step_action_remote_test.go",
    "content": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/common/git\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype stepActionRemoteMocks struct {\n\tmock.Mock\n}\n\nfunc (sarm *stepActionRemoteMocks) readAction(_ context.Context, step *model.Step, actionDir string, actionPath string, readFile actionYamlReader, writeFile fileWriter) (*model.Action, error) {\n\targs := sarm.Called(step, actionDir, actionPath, readFile, writeFile)\n\treturn args.Get(0).(*model.Action), args.Error(1)\n}\n\nfunc (sarm *stepActionRemoteMocks) runAction(step actionStep, actionDir string, remoteAction *remoteAction) common.Executor {\n\targs := sarm.Called(step, actionDir, remoteAction)\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc TestStepActionRemote(t *testing.T) {\n\ttable := []struct {\n\t\tname      string\n\t\tstepModel *model.Step\n\t\tresult    *model.StepResult\n\t\tmocks     struct {\n\t\t\tenv    bool\n\t\t\tcloned bool\n\t\t\tread   bool\n\t\t\trun    bool\n\t\t}\n\t\trunError error\n\t}{\n\t\t{\n\t\t\tname: \"run-successful\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"remote/action@v1\",\n\t\t\t},\n\t\t\tresult: &model.StepResult{\n\t\t\t\tConclusion: model.StepStatusSuccess,\n\t\t\t\tOutcome:    model.StepStatusSuccess,\n\t\t\t\tOutputs:    map[string]string{},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv    bool\n\t\t\t\tcloned bool\n\t\t\t\tread   bool\n\t\t\t\trun    bool\n\t\t\t}{\n\t\t\t\tenv:    true,\n\t\t\t\tcloned: true,\n\t\t\t\tread:   true,\n\t\t\t\trun:    true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"run-skipped\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"remote/action@v1\",\n\t\t\t\tIf:   yaml.Node{Value: \"false\"},\n\t\t\t},\n\t\t\tresult: &model.StepResult{\n\t\t\t\tConclusion: model.StepStatusSkipped,\n\t\t\t\tOutcome:    model.StepStatusSkipped,\n\t\t\t\tOutputs:    map[string]string{},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv    bool\n\t\t\t\tcloned bool\n\t\t\t\tread   bool\n\t\t\t\trun    bool\n\t\t\t}{\n\t\t\t\tenv:    true,\n\t\t\t\tcloned: true,\n\t\t\t\tread:   true,\n\t\t\t\trun:    false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"run-error\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"remote/action@v1\",\n\t\t\t},\n\t\t\tresult: &model.StepResult{\n\t\t\t\tConclusion: model.StepStatusFailure,\n\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\tOutputs:    map[string]string{},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv    bool\n\t\t\t\tcloned bool\n\t\t\t\tread   bool\n\t\t\t\trun    bool\n\t\t\t}{\n\t\t\t\tenv:    true,\n\t\t\t\tcloned: true,\n\t\t\t\tread:   true,\n\t\t\t\trun:    true,\n\t\t\t},\n\t\t\trunError: errors.New(\"error\"),\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\n\t\t\tcm := &containerMock{}\n\t\t\tsarm := &stepActionRemoteMocks{}\n\n\t\t\tclonedAction := false\n\n\t\t\torigStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor\n\t\t\tstepActionRemoteNewCloneExecutor = func(_ git.NewGitCloneExecutorInput) common.Executor {\n\t\t\t\treturn func(_ context.Context) error {\n\t\t\t\t\tclonedAction = true\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefer (func() {\n\t\t\t\tstepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor\n\t\t\t})()\n\n\t\t\tsar := &stepActionRemote{\n\t\t\t\tRunContext: &RunContext{\n\t\t\t\t\tConfig: &Config{\n\t\t\t\t\t\tGitHubInstance: \"github.com\",\n\t\t\t\t\t},\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tJobID: \"1\",\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\t\"1\": {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tStepResults:  map[string]*model.StepResult{},\n\t\t\t\t\tJobContainer: cm,\n\t\t\t\t},\n\t\t\t\tStep:       tt.stepModel,\n\t\t\t\treadAction: sarm.readAction,\n\t\t\t\trunAction:  sarm.runAction,\n\t\t\t}\n\t\t\tsar.RunContext.ExprEval = sar.RunContext.NewExpressionEvaluator(ctx)\n\n\t\t\tsuffixMatcher := func(suffix string) interface{} {\n\t\t\t\treturn mock.MatchedBy(func(actionDir string) bool {\n\t\t\t\t\treturn strings.HasSuffix(actionDir, suffix)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif tt.mocks.read {\n\t\t\t\tsarm.On(\"readAction\", sar.Step, suffixMatcher(\"act/remote-action@v1\"), \"\", mock.Anything, mock.Anything).Return(&model.Action{}, nil)\n\t\t\t}\n\t\t\tif tt.mocks.run {\n\t\t\t\tsarm.On(\"runAction\", sar, suffixMatcher(\"act/remote-action@v1\"), newRemoteAction(sar.Step.Uses)).Return(func(_ context.Context) error { return tt.runError })\n\n\t\t\t\tcm.On(\"Copy\", \"/var/run/act\", mock.AnythingOfType(\"[]*container.FileEntry\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/envs.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/statecmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/outputcmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/SUMMARY.md\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\t\t\t\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/pathcmd.txt\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\t\t\t}\n\n\t\t\terr := sar.pre()(ctx)\n\t\t\tif err == nil {\n\t\t\t\terr = sar.main()(ctx)\n\t\t\t}\n\n\t\t\tassert.ErrorIs(t, err, tt.runError)\n\t\t\tassert.Equal(t, tt.mocks.cloned, clonedAction)\n\t\t\tassert.Equal(t, sar.RunContext.StepResults[\"step\"], tt.result)\n\n\t\t\tsarm.AssertExpectations(t)\n\t\t\tcm.AssertExpectations(t)\n\t\t})\n\t}\n}\n\nfunc TestStepActionRemotePre(t *testing.T) {\n\ttable := []struct {\n\t\tname      string\n\t\tstepModel *model.Step\n\t}{\n\t\t{\n\t\t\tname: \"run-pre\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tUses: \"org/repo/path@ref\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\n\t\t\tclonedAction := false\n\t\t\tsarm := &stepActionRemoteMocks{}\n\n\t\t\torigStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor\n\t\t\tstepActionRemoteNewCloneExecutor = func(_ git.NewGitCloneExecutorInput) common.Executor {\n\t\t\t\treturn func(_ context.Context) error {\n\t\t\t\t\tclonedAction = true\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefer (func() {\n\t\t\t\tstepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor\n\t\t\t})()\n\n\t\t\tsar := &stepActionRemote{\n\t\t\t\tStep: tt.stepModel,\n\t\t\t\tRunContext: &RunContext{\n\t\t\t\t\tConfig: &Config{\n\t\t\t\t\t\tGitHubInstance: \"https://github.com\",\n\t\t\t\t\t},\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tJobID: \"1\",\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\t\"1\": {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\treadAction: sarm.readAction,\n\t\t\t}\n\n\t\t\tsuffixMatcher := func(suffix string) interface{} {\n\t\t\t\treturn mock.MatchedBy(func(actionDir string) bool {\n\t\t\t\t\treturn strings.HasSuffix(actionDir, suffix)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tsarm.On(\"readAction\", sar.Step, suffixMatcher(\"org-repo-path@ref\"), \"path\", mock.Anything, mock.Anything).Return(&model.Action{}, nil)\n\n\t\t\terr := sar.pre()(ctx)\n\n\t\t\tassert.Nil(t, err)\n\t\t\tassert.Equal(t, true, clonedAction)\n\n\t\t\tsarm.AssertExpectations(t)\n\t\t})\n\t}\n}\n\nfunc TestStepActionRemotePreThroughAction(t *testing.T) {\n\ttable := []struct {\n\t\tname      string\n\t\tstepModel *model.Step\n\t}{\n\t\t{\n\t\t\tname: \"run-pre\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tUses: \"org/repo/path@ref\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\n\t\t\tclonedAction := false\n\t\t\tsarm := &stepActionRemoteMocks{}\n\n\t\t\torigStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor\n\t\t\tstepActionRemoteNewCloneExecutor = func(input git.NewGitCloneExecutorInput) common.Executor {\n\t\t\t\treturn func(_ context.Context) error {\n\t\t\t\t\tif input.URL == \"https://github.com/org/repo\" {\n\t\t\t\t\t\tclonedAction = true\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefer (func() {\n\t\t\t\tstepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor\n\t\t\t})()\n\n\t\t\tsar := &stepActionRemote{\n\t\t\t\tStep: tt.stepModel,\n\t\t\t\tRunContext: &RunContext{\n\t\t\t\t\tConfig: &Config{\n\t\t\t\t\t\tGitHubInstance:                \"https://enterprise.github.com\",\n\t\t\t\t\t\tReplaceGheActionWithGithubCom: []string{\"org/repo\"},\n\t\t\t\t\t},\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tJobID: \"1\",\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\t\"1\": {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\treadAction: sarm.readAction,\n\t\t\t}\n\n\t\t\tsuffixMatcher := func(suffix string) interface{} {\n\t\t\t\treturn mock.MatchedBy(func(actionDir string) bool {\n\t\t\t\t\treturn strings.HasSuffix(actionDir, suffix)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tsarm.On(\"readAction\", sar.Step, suffixMatcher(\"org-repo-path@ref\"), \"path\", mock.Anything, mock.Anything).Return(&model.Action{}, nil)\n\n\t\t\terr := sar.pre()(ctx)\n\n\t\t\tassert.Nil(t, err)\n\t\t\tassert.Equal(t, true, clonedAction)\n\n\t\t\tsarm.AssertExpectations(t)\n\t\t})\n\t}\n}\n\nfunc TestStepActionRemotePreThroughActionToken(t *testing.T) {\n\ttable := []struct {\n\t\tname      string\n\t\tstepModel *model.Step\n\t}{\n\t\t{\n\t\t\tname: \"run-pre\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tUses: \"org/repo/path@ref\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\n\t\t\tclonedAction := false\n\t\t\tsarm := &stepActionRemoteMocks{}\n\n\t\t\torigStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor\n\t\t\tstepActionRemoteNewCloneExecutor = func(input git.NewGitCloneExecutorInput) common.Executor {\n\t\t\t\treturn func(_ context.Context) error {\n\t\t\t\t\tif input.URL == \"https://github.com/org/repo\" && input.Token == \"PRIVATE_ACTIONS_TOKEN_ON_GITHUB\" {\n\t\t\t\t\t\tclonedAction = true\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefer (func() {\n\t\t\t\tstepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor\n\t\t\t})()\n\n\t\t\tsar := &stepActionRemote{\n\t\t\t\tStep: tt.stepModel,\n\t\t\t\tRunContext: &RunContext{\n\t\t\t\t\tConfig: &Config{\n\t\t\t\t\t\tGitHubInstance:                     \"https://enterprise.github.com\",\n\t\t\t\t\t\tReplaceGheActionWithGithubCom:      []string{\"org/repo\"},\n\t\t\t\t\t\tReplaceGheActionTokenWithGithubCom: \"PRIVATE_ACTIONS_TOKEN_ON_GITHUB\",\n\t\t\t\t\t},\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tJobID: \"1\",\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\t\"1\": {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\treadAction: sarm.readAction,\n\t\t\t}\n\n\t\t\tsuffixMatcher := func(suffix string) interface{} {\n\t\t\t\treturn mock.MatchedBy(func(actionDir string) bool {\n\t\t\t\t\treturn strings.HasSuffix(actionDir, suffix)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tsarm.On(\"readAction\", sar.Step, suffixMatcher(\"org-repo-path@ref\"), \"path\", mock.Anything, mock.Anything).Return(&model.Action{}, nil)\n\n\t\t\terr := sar.pre()(ctx)\n\n\t\t\tassert.Nil(t, err)\n\t\t\tassert.Equal(t, true, clonedAction)\n\n\t\t\tsarm.AssertExpectations(t)\n\t\t})\n\t}\n}\n\nfunc TestStepActionRemotePost(t *testing.T) {\n\ttable := []struct {\n\t\tname               string\n\t\tstepModel          *model.Step\n\t\tactionModel        *model.Action\n\t\tinitialStepResults map[string]*model.StepResult\n\t\tIntraActionState   map[string]map[string]string\n\t\texpectedEnv        map[string]string\n\t\terr                error\n\t\tmocks              struct {\n\t\t\tenv  bool\n\t\t\texec bool\n\t\t}\n\t}{\n\t\t{\n\t\t\tname: \"main-success\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"remote/action@v1\",\n\t\t\t},\n\t\t\tactionModel: &model.Action{\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tPost:   \"post.js\",\n\t\t\t\t\tPostIf: \"always()\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tinitialStepResults: map[string]*model.StepResult{\n\t\t\t\t\"step\": {\n\t\t\t\t\tConclusion: model.StepStatusSuccess,\n\t\t\t\t\tOutcome:    model.StepStatusSuccess,\n\t\t\t\t\tOutputs:    map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t\tIntraActionState: map[string]map[string]string{\n\t\t\t\t\"step\": {\n\t\t\t\t\t\"key\": \"value\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedEnv: map[string]string{\n\t\t\t\t\"STATE_key\": \"value\",\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv  bool\n\t\t\t\texec bool\n\t\t\t}{\n\t\t\t\tenv:  true,\n\t\t\t\texec: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"main-failed\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"remote/action@v1\",\n\t\t\t},\n\t\t\tactionModel: &model.Action{\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tPost:   \"post.js\",\n\t\t\t\t\tPostIf: \"always()\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tinitialStepResults: map[string]*model.StepResult{\n\t\t\t\t\"step\": {\n\t\t\t\t\tConclusion: model.StepStatusFailure,\n\t\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\t\tOutputs:    map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv  bool\n\t\t\t\texec bool\n\t\t\t}{\n\t\t\t\tenv:  true,\n\t\t\t\texec: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"skip-if-failed\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tUses: \"remote/action@v1\",\n\t\t\t},\n\t\t\tactionModel: &model.Action{\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tPost:   \"post.js\",\n\t\t\t\t\tPostIf: \"success()\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tinitialStepResults: map[string]*model.StepResult{\n\t\t\t\t\"step\": {\n\t\t\t\t\tConclusion: model.StepStatusFailure,\n\t\t\t\t\tOutcome:    model.StepStatusFailure,\n\t\t\t\t\tOutputs:    map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv  bool\n\t\t\t\texec bool\n\t\t\t}{\n\t\t\t\tenv:  true,\n\t\t\t\texec: false,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"skip-if-main-skipped\",\n\t\t\tstepModel: &model.Step{\n\t\t\t\tID:   \"step\",\n\t\t\t\tIf:   yaml.Node{Value: \"failure()\"},\n\t\t\t\tUses: \"remote/action@v1\",\n\t\t\t},\n\t\t\tactionModel: &model.Action{\n\t\t\t\tRuns: model.ActionRuns{\n\t\t\t\t\tUsing:  \"node16\",\n\t\t\t\t\tPost:   \"post.js\",\n\t\t\t\t\tPostIf: \"always()\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tinitialStepResults: map[string]*model.StepResult{\n\t\t\t\t\"step\": {\n\t\t\t\t\tConclusion: model.StepStatusSkipped,\n\t\t\t\t\tOutcome:    model.StepStatusSkipped,\n\t\t\t\t\tOutputs:    map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t\tmocks: struct {\n\t\t\t\tenv  bool\n\t\t\t\texec bool\n\t\t\t}{\n\t\t\t\tenv:  false,\n\t\t\t\texec: false,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tctx := context.Background()\n\n\t\t\tcm := &containerMock{}\n\n\t\t\tsar := &stepActionRemote{\n\t\t\t\tenv: map[string]string{},\n\t\t\t\tRunContext: &RunContext{\n\t\t\t\t\tConfig: &Config{\n\t\t\t\t\t\tGitHubInstance: \"https://github.com\",\n\t\t\t\t\t},\n\t\t\t\t\tJobContainer: cm,\n\t\t\t\t\tRun: &model.Run{\n\t\t\t\t\t\tJobID: \"1\",\n\t\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\t\"1\": {},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tStepResults:      tt.initialStepResults,\n\t\t\t\t\tIntraActionState: tt.IntraActionState,\n\t\t\t\t\tnodeToolFullPath: \"node\",\n\t\t\t\t},\n\t\t\t\tStep:   tt.stepModel,\n\t\t\t\taction: tt.actionModel,\n\t\t\t}\n\t\t\tsar.RunContext.ExprEval = sar.RunContext.NewExpressionEvaluator(ctx)\n\n\t\t\tif tt.mocks.exec {\n\t\t\t\tcm.On(\"Exec\", []string{\"node\", \"/var/run/act/actions/remote-action@v1/post.js\"}, sar.env, \"\", \"\").Return(func(_ context.Context) error { return tt.err })\n\n\t\t\t\tcm.On(\"Copy\", \"/var/run/act\", mock.AnythingOfType(\"[]*container.FileEntry\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/envs.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/statecmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/outputcmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\n\t\t\t\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/SUMMARY.md\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\t\t\t\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/pathcmd.txt\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\t\t\t}\n\n\t\t\terr := sar.post()(ctx)\n\n\t\t\tassert.Equal(t, tt.err, err)\n\t\t\tif tt.expectedEnv != nil {\n\t\t\t\tfor key, value := range tt.expectedEnv {\n\t\t\t\t\tassert.Equal(t, value, sar.env[key])\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Enshure that StepResults is nil in this test\n\t\t\tassert.Equal(t, sar.RunContext.StepResults[\"post-step\"], (*model.StepResult)(nil))\n\t\t\tcm.AssertExpectations(t)\n\t\t})\n\t}\n}\n\nfunc Test_safeFilename(t *testing.T) {\n\ttests := []struct {\n\t\ts    string\n\t\twant string\n\t}{\n\t\t{\n\t\t\ts:    \"https://test.com/test/\",\n\t\t\twant: \"https---test.com-test-\",\n\t\t},\n\t\t{\n\t\t\ts:    `<>:\"/\\|?*`,\n\t\t\twant: \"---------\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.s, func(t *testing.T) {\n\t\t\tassert.Equalf(t, tt.want, safeFilename(tt.s), \"safeFilename(%v)\", tt.s)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/runner/step_docker.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/kballard/go-shellquote\"\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype stepDocker struct {\n\tStep       *model.Step\n\tRunContext *RunContext\n\tenv        map[string]string\n}\n\nfunc (sd *stepDocker) pre() common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc (sd *stepDocker) main() common.Executor {\n\tsd.env = map[string]string{}\n\n\treturn runStepExecutor(sd, stepStageMain, sd.runUsesContainer())\n}\n\nfunc (sd *stepDocker) post() common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc (sd *stepDocker) getRunContext() *RunContext {\n\treturn sd.RunContext\n}\n\nfunc (sd *stepDocker) getGithubContext(ctx context.Context) *model.GithubContext {\n\treturn sd.getRunContext().getGithubContext(ctx)\n}\n\nfunc (sd *stepDocker) getStepModel() *model.Step {\n\treturn sd.Step\n}\n\nfunc (sd *stepDocker) getEnv() *map[string]string {\n\treturn &sd.env\n}\n\nfunc (sd *stepDocker) getIfExpression(_ context.Context, _ stepStage) string {\n\treturn sd.Step.If.Value\n}\n\nfunc (sd *stepDocker) runUsesContainer() common.Executor {\n\trc := sd.RunContext\n\tstep := sd.Step\n\n\treturn func(ctx context.Context) error {\n\t\timage := strings.TrimPrefix(step.Uses, \"docker://\")\n\t\teval := rc.NewExpressionEvaluator(ctx)\n\t\tcmd, err := shellquote.Split(eval.Interpolate(ctx, step.With[\"args\"]))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvar entrypoint []string\n\t\tif entry := eval.Interpolate(ctx, step.With[\"entrypoint\"]); entry != \"\" {\n\t\t\tentrypoint = []string{entry}\n\t\t}\n\n\t\tstepContainer := sd.newStepContainer(ctx, image, cmd, entrypoint)\n\n\t\treturn common.NewPipelineExecutor(\n\t\t\tstepContainer.Pull(rc.Config.ForcePull),\n\t\t\tstepContainer.Remove().IfBool(!rc.Config.ReuseContainers),\n\t\t\tstepContainer.Create(rc.Config.ContainerCapAdd, rc.Config.ContainerCapDrop),\n\t\t\tstepContainer.Start(true),\n\t\t).Finally(\n\t\t\tstepContainer.Remove().IfBool(!rc.Config.ReuseContainers),\n\t\t).Finally(stepContainer.Close())(ctx)\n\t}\n}\n\nvar (\n\tContainerNewContainer = container.NewContainer\n)\n\nfunc (sd *stepDocker) newStepContainer(ctx context.Context, image string, cmd []string, entrypoint []string) container.Container {\n\trc := sd.RunContext\n\tstep := sd.Step\n\n\trawLogger := common.Logger(ctx).WithField(\"raw_output\", true)\n\tlogWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool {\n\t\tif rc.Config.LogOutput {\n\t\t\trawLogger.Infof(\"%s\", s)\n\t\t} else {\n\t\t\trawLogger.Debugf(\"%s\", s)\n\t\t}\n\t\treturn true\n\t})\n\tenvList := make([]string, 0)\n\tfor k, v := range sd.env {\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", k, v))\n\t}\n\n\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_TOOL_CACHE\", \"/opt/hostedtoolcache\"))\n\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_OS\", \"Linux\"))\n\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_ARCH\", container.RunnerArch(ctx)))\n\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_TEMP\", \"/tmp\"))\n\n\tbinds, mounts := rc.GetBindsAndMounts()\n\tstepContainer := ContainerNewContainer(&container.NewContainerInput{\n\t\tCmd:         cmd,\n\t\tEntrypoint:  entrypoint,\n\t\tWorkingDir:  rc.JobContainer.ToContainerPath(rc.Config.Workdir),\n\t\tImage:       image,\n\t\tUsername:    rc.Config.Secrets[\"DOCKER_USERNAME\"],\n\t\tPassword:    rc.Config.Secrets[\"DOCKER_PASSWORD\"],\n\t\tName:        createContainerName(rc.jobContainerName(), step.ID),\n\t\tEnv:         envList,\n\t\tMounts:      mounts,\n\t\tNetworkMode: fmt.Sprintf(\"container:%s\", rc.jobContainerName()),\n\t\tBinds:       binds,\n\t\tStdout:      logWriter,\n\t\tStderr:      logWriter,\n\t\tPrivileged:  rc.Config.Privileged,\n\t\tUsernsMode:  rc.Config.UsernsMode,\n\t\tPlatform:    rc.Config.ContainerArchitecture,\n\t})\n\treturn stepContainer\n}\n"
  },
  {
    "path": "pkg/runner/step_docker_test.go",
    "content": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n)\n\nfunc TestStepDockerMain(t *testing.T) {\n\tcm := &containerMock{}\n\n\tvar input *container.NewContainerInput\n\n\t// mock the new container call\n\torigContainerNewContainer := ContainerNewContainer\n\tContainerNewContainer = func(containerInput *container.NewContainerInput) container.ExecutionsEnvironment {\n\t\tinput = containerInput\n\t\treturn cm\n\t}\n\tdefer (func() {\n\t\tContainerNewContainer = origContainerNewContainer\n\t})()\n\n\tctx := context.Background()\n\n\tsd := &stepDocker{\n\t\tRunContext: &RunContext{\n\t\t\tStepResults: map[string]*model.StepResult{},\n\t\t\tConfig:      &Config{},\n\t\t\tRun: &model.Run{\n\t\t\t\tJobID: \"1\",\n\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\"1\": {\n\t\t\t\t\t\t\tDefaults: model.Defaults{\n\t\t\t\t\t\t\t\tRun: model.RunDefaults{\n\t\t\t\t\t\t\t\t\tShell: \"bash\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tJobContainer: cm,\n\t\t},\n\t\tStep: &model.Step{\n\t\t\tID:               \"1\",\n\t\t\tUses:             \"docker://node:14\",\n\t\t\tWorkingDirectory: \"workdir\",\n\t\t},\n\t}\n\tsd.RunContext.ExprEval = sd.RunContext.NewExpressionEvaluator(ctx)\n\n\tcm.On(\"Pull\", false).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"Remove\").Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"Create\", []string(nil), []string(nil)).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"Start\", true).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"Close\").Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"Copy\", \"/var/run/act\", mock.AnythingOfType(\"[]*container.FileEntry\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/envs.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/statecmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/outputcmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/SUMMARY.md\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/pathcmd.txt\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\n\terr := sd.main()(ctx)\n\tassert.Nil(t, err)\n\n\tassert.Equal(t, \"node:14\", input.Image)\n\n\tcm.AssertExpectations(t)\n}\n\nfunc TestStepDockerPrePost(t *testing.T) {\n\tctx := context.Background()\n\tsd := &stepDocker{}\n\n\terr := sd.pre()(ctx)\n\tassert.Nil(t, err)\n\n\terr = sd.post()(ctx)\n\tassert.Nil(t, err)\n}\n"
  },
  {
    "path": "pkg/runner/step_factory.go",
    "content": "package runner\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype stepFactory interface {\n\tnewStep(step *model.Step, rc *RunContext) (step, error)\n}\n\ntype stepFactoryImpl struct{}\n\nfunc (sf *stepFactoryImpl) newStep(stepModel *model.Step, rc *RunContext) (step, error) {\n\tswitch stepModel.Type() {\n\tcase model.StepTypeInvalid:\n\t\treturn nil, fmt.Errorf(\"Invalid run/uses syntax for job:%s step:%+v\", rc.Run, stepModel)\n\tcase model.StepTypeRun:\n\t\treturn &stepRun{\n\t\t\tStep:       stepModel,\n\t\t\tRunContext: rc,\n\t\t}, nil\n\tcase model.StepTypeUsesActionLocal:\n\t\treturn &stepActionLocal{\n\t\t\tStep:       stepModel,\n\t\t\tRunContext: rc,\n\t\t\treadAction: readActionImpl,\n\t\t\trunAction:  runActionImpl,\n\t\t}, nil\n\tcase model.StepTypeUsesActionRemote:\n\t\treturn &stepActionRemote{\n\t\t\tStep:       stepModel,\n\t\t\tRunContext: rc,\n\t\t\treadAction: readActionImpl,\n\t\t\trunAction:  runActionImpl,\n\t\t}, nil\n\tcase model.StepTypeUsesDockerURL:\n\t\treturn &stepDocker{\n\t\t\tStep:       stepModel,\n\t\t\tRunContext: rc,\n\t\t}, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"Unable to determine how to run job:%s step:%+v\", rc.Run, stepModel)\n}\n"
  },
  {
    "path": "pkg/runner/step_factory_test.go",
    "content": "package runner\n\nimport (\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/model\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestStepFactoryNewStep(t *testing.T) {\n\ttable := []struct {\n\t\tname  string\n\t\tmodel *model.Step\n\t\tcheck func(s step) bool\n\t}{\n\t\t{\n\t\t\tname: \"StepRemoteAction\",\n\t\t\tmodel: &model.Step{\n\t\t\t\tUses: \"remote/action@v1\",\n\t\t\t},\n\t\t\tcheck: func(s step) bool {\n\t\t\t\t_, ok := s.(*stepActionRemote)\n\t\t\t\treturn ok\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"StepLocalAction\",\n\t\t\tmodel: &model.Step{\n\t\t\t\tUses: \"./action@v1\",\n\t\t\t},\n\t\t\tcheck: func(s step) bool {\n\t\t\t\t_, ok := s.(*stepActionLocal)\n\t\t\t\treturn ok\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"StepDocker\",\n\t\t\tmodel: &model.Step{\n\t\t\t\tUses: \"docker://image:tag\",\n\t\t\t},\n\t\t\tcheck: func(s step) bool {\n\t\t\t\t_, ok := s.(*stepDocker)\n\t\t\t\treturn ok\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"StepRun\",\n\t\t\tmodel: &model.Step{\n\t\t\t\tRun: \"cmd\",\n\t\t\t},\n\t\t\tcheck: func(s step) bool {\n\t\t\t\t_, ok := s.(*stepRun)\n\t\t\t\treturn ok\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tsf := &stepFactoryImpl{}\n\n\t\t\tstep, err := sf.newStep(tt.model, &RunContext{})\n\n\t\t\tassert.True(t, tt.check((step)))\n\t\t\tassert.Nil(t, err)\n\t\t})\n\t}\n}\n\nfunc TestStepFactoryInvalidStep(t *testing.T) {\n\tmodel := &model.Step{\n\t\tUses: \"remote/action@v1\",\n\t\tRun:  \"cmd\",\n\t}\n\n\tsf := &stepFactoryImpl{}\n\n\t_, err := sf.newStep(model, &RunContext{})\n\n\tassert.Error(t, err)\n}\n"
  },
  {
    "path": "pkg/runner/step_run.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/kballard/go-shellquote\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/lookpath\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\ntype stepRun struct {\n\tStep             *model.Step\n\tRunContext       *RunContext\n\tcmd              []string\n\tcmdline          string\n\tenv              map[string]string\n\tWorkingDirectory string\n}\n\nfunc (sr *stepRun) pre() common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc (sr *stepRun) main() common.Executor {\n\tsr.env = map[string]string{}\n\treturn runStepExecutor(sr, stepStageMain, common.NewPipelineExecutor(\n\t\tsr.setupShellCommandExecutor(),\n\t\tfunc(ctx context.Context) error {\n\t\t\tsr.getRunContext().ApplyExtraPath(ctx, &sr.env)\n\t\t\tif he, ok := sr.getRunContext().JobContainer.(*container.HostEnvironment); ok && he != nil {\n\t\t\t\treturn he.ExecWithCmdLine(sr.cmd, sr.cmdline, sr.env, \"\", sr.WorkingDirectory)(ctx)\n\t\t\t}\n\t\t\treturn sr.getRunContext().JobContainer.Exec(sr.cmd, sr.env, \"\", sr.WorkingDirectory)(ctx)\n\t\t},\n\t))\n}\n\nfunc (sr *stepRun) post() common.Executor {\n\treturn func(_ context.Context) error {\n\t\treturn nil\n\t}\n}\n\nfunc (sr *stepRun) getRunContext() *RunContext {\n\treturn sr.RunContext\n}\n\nfunc (sr *stepRun) getGithubContext(ctx context.Context) *model.GithubContext {\n\treturn sr.getRunContext().getGithubContext(ctx)\n}\n\nfunc (sr *stepRun) getStepModel() *model.Step {\n\treturn sr.Step\n}\n\nfunc (sr *stepRun) getEnv() *map[string]string {\n\treturn &sr.env\n}\n\nfunc (sr *stepRun) getIfExpression(_ context.Context, _ stepStage) string {\n\treturn sr.Step.If.Value\n}\n\nfunc (sr *stepRun) setupShellCommandExecutor() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tscriptName, script, err := sr.setupShellCommand(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\trc := sr.getRunContext()\n\t\treturn rc.JobContainer.Copy(rc.JobContainer.GetActPath(), &container.FileEntry{\n\t\t\tName: scriptName,\n\t\t\tMode: 0o755,\n\t\t\tBody: script,\n\t\t})(ctx)\n\t}\n}\n\nfunc getScriptName(rc *RunContext, step *model.Step) string {\n\tscriptName := step.ID\n\tfor rcs := rc; rcs.Parent != nil; rcs = rcs.Parent {\n\t\tscriptName = fmt.Sprintf(\"%s-composite-%s\", rcs.Parent.CurrentStep, scriptName)\n\t}\n\treturn fmt.Sprintf(\"workflow/%s\", scriptName)\n}\n\n// TODO: Currently we just ignore top level keys, BUT we should return proper error on them\n// BUTx2 I leave this for when we rewrite act to use actionlint for workflow validation\n// so we return proper errors before any execution or spawning containers\n// it will error anyway with:\n// OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: \"${{\": executable file not found in $PATH: unknown\nfunc (sr *stepRun) setupShellCommand(ctx context.Context) (name, script string, err error) {\n\tlogger := common.Logger(ctx)\n\tsr.setupShell(ctx)\n\tsr.setupWorkingDirectory(ctx)\n\n\tstep := sr.Step\n\n\tscript = sr.RunContext.NewStepExpressionEvaluator(ctx, sr).Interpolate(ctx, step.Run)\n\n\tscCmd := step.ShellCommand()\n\n\tname = getScriptName(sr.RunContext, step)\n\n\t// Reference: https://github.com/actions/runner/blob/8109c962f09d9acc473d92c595ff43afceddb347/src/Runner.Worker/Handlers/ScriptHandlerHelpers.cs#L47-L64\n\t// Reference: https://github.com/actions/runner/blob/8109c962f09d9acc473d92c595ff43afceddb347/src/Runner.Worker/Handlers/ScriptHandlerHelpers.cs#L19-L27\n\trunPrepend := \"\"\n\trunAppend := \"\"\n\tswitch step.Shell {\n\tcase \"bash\", \"sh\":\n\t\tname += \".sh\"\n\tcase \"pwsh\", \"powershell\":\n\t\tname += \".ps1\"\n\t\trunPrepend = \"$ErrorActionPreference = 'stop'\"\n\t\trunAppend = \"if ((Test-Path -LiteralPath variable:/LASTEXITCODE)) { exit $LASTEXITCODE }\"\n\tcase \"cmd\":\n\t\tname += \".cmd\"\n\t\trunPrepend = \"@echo off\"\n\tcase \"python\":\n\t\tname += \".py\"\n\t}\n\n\tscript = fmt.Sprintf(\"%s\\n%s\\n%s\", runPrepend, script, runAppend)\n\n\tif !strings.Contains(script, \"::add-mask::\") && !sr.RunContext.Config.InsecureSecrets {\n\t\tlogger.Debugf(\"Wrote command \\n%s\\n to '%s'\", script, name)\n\t} else {\n\t\tlogger.Debugf(\"Wrote add-mask command to '%s'\", name)\n\t}\n\n\trc := sr.getRunContext()\n\tscriptPath := fmt.Sprintf(\"%s/%s\", rc.JobContainer.GetActPath(), name)\n\tsr.cmdline = strings.Replace(scCmd, `{0}`, scriptPath, 1)\n\tsr.cmd, err = shellquote.Split(sr.cmdline)\n\n\treturn name, script, err\n}\n\ntype localEnv struct {\n\tenv map[string]string\n}\n\nfunc (l *localEnv) Getenv(name string) string {\n\tif runtime.GOOS == \"windows\" {\n\t\tfor k, v := range l.env {\n\t\t\tif strings.EqualFold(name, k) {\n\t\t\t\treturn v\n\t\t\t}\n\t\t}\n\t\treturn \"\"\n\t}\n\treturn l.env[name]\n}\n\nfunc (sr *stepRun) setupShell(ctx context.Context) {\n\trc := sr.RunContext\n\tstep := sr.Step\n\n\tif step.Shell == \"\" {\n\t\tstep.WorkflowShell = rc.Run.Job().Defaults.Run.Shell\n\t} else {\n\t\tstep.WorkflowShell = step.Shell\n\t}\n\n\tstep.WorkflowShell = rc.NewExpressionEvaluator(ctx).Interpolate(ctx, step.WorkflowShell)\n\n\tif step.WorkflowShell == \"\" {\n\t\tstep.WorkflowShell = rc.Run.Workflow.Defaults.Run.Shell\n\t}\n\n\tif step.WorkflowShell == \"\" {\n\t\tif _, ok := rc.JobContainer.(*container.HostEnvironment); ok {\n\t\t\tshellWithFallback := []string{\"bash\", \"sh\"}\n\t\t\t// Don't use bash on windows by default, if not using a docker container\n\t\t\tif runtime.GOOS == \"windows\" {\n\t\t\t\tshellWithFallback = []string{\"pwsh\", \"powershell\"}\n\t\t\t}\n\t\t\tstep.Shell = shellWithFallback[0]\n\t\t\tlenv := &localEnv{env: map[string]string{}}\n\t\t\tfor k, v := range sr.env {\n\t\t\t\tlenv.env[k] = v\n\t\t\t}\n\t\t\tsr.getRunContext().ApplyExtraPath(ctx, &lenv.env)\n\t\t\t_, err := lookpath.LookPath2(shellWithFallback[0], lenv)\n\t\t\tif err != nil {\n\t\t\t\tstep.Shell = shellWithFallback[1]\n\t\t\t}\n\t\t} else if containerImage := rc.containerImage(ctx); containerImage != \"\" {\n\t\t\t// Currently only linux containers are supported, use sh by default like actions/runner\n\t\t\tstep.Shell = \"sh\"\n\t\t}\n\t} else {\n\t\tstep.Shell = step.WorkflowShell\n\t}\n}\n\nfunc (sr *stepRun) setupWorkingDirectory(ctx context.Context) {\n\trc := sr.RunContext\n\tstep := sr.Step\n\tworkingdirectory := \"\"\n\n\tif step.WorkingDirectory == \"\" {\n\t\tworkingdirectory = rc.Run.Job().Defaults.Run.WorkingDirectory\n\t} else {\n\t\tworkingdirectory = step.WorkingDirectory\n\t}\n\n\t// jobs can receive context values, so we interpolate\n\tworkingdirectory = rc.NewExpressionEvaluator(ctx).Interpolate(ctx, workingdirectory)\n\n\t// but top level keys in workflow file like `defaults` or `env` can't\n\tif workingdirectory == \"\" {\n\t\tworkingdirectory = rc.Run.Workflow.Defaults.Run.WorkingDirectory\n\t}\n\tsr.WorkingDirectory = workingdirectory\n}\n"
  },
  {
    "path": "pkg/runner/step_run_test.go",
    "content": "package runner\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n\n\t\"github.com/nektos/act/pkg/container\"\n\t\"github.com/nektos/act/pkg/model\"\n)\n\nfunc TestStepRun(t *testing.T) {\n\tcm := &containerMock{}\n\tfileEntry := &container.FileEntry{\n\t\tName: \"workflow/1.sh\",\n\t\tMode: 0o755,\n\t\tBody: \"\\ncmd\\n\",\n\t}\n\n\tsr := &stepRun{\n\t\tRunContext: &RunContext{\n\t\t\tStepResults: map[string]*model.StepResult{},\n\t\t\tExprEval:    &expressionEvaluator{},\n\t\t\tConfig:      &Config{},\n\t\t\tRun: &model.Run{\n\t\t\t\tJobID: \"1\",\n\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\"1\": {\n\t\t\t\t\t\t\tDefaults: model.Defaults{\n\t\t\t\t\t\t\t\tRun: model.RunDefaults{\n\t\t\t\t\t\t\t\t\tShell: \"bash\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tJobContainer: cm,\n\t\t},\n\t\tStep: &model.Step{\n\t\t\tID:               \"1\",\n\t\t\tRun:              \"cmd\",\n\t\t\tWorkingDirectory: \"workdir\",\n\t\t},\n\t}\n\n\tcm.On(\"Copy\", \"/var/run/act\", []*container.FileEntry{fileEntry}).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\tcm.On(\"Exec\", []string{\"bash\", \"--noprofile\", \"--norc\", \"-e\", \"-o\", \"pipefail\", \"/var/run/act/workflow/1.sh\"}, mock.AnythingOfType(\"map[string]string\"), \"\", \"workdir\").Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"Copy\", \"/var/run/act\", mock.AnythingOfType(\"[]*container.FileEntry\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/envs.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/statecmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tcm.On(\"UpdateFromEnv\", \"/var/run/act/workflow/outputcmd.txt\", mock.AnythingOfType(\"*map[string]string\")).Return(func(_ context.Context) error {\n\t\treturn nil\n\t})\n\n\tctx := context.Background()\n\n\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/SUMMARY.md\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\tcm.On(\"GetContainerArchive\", ctx, \"/var/run/act/workflow/pathcmd.txt\").Return(io.NopCloser(&bytes.Buffer{}), nil)\n\n\terr := sr.main()(ctx)\n\tassert.Nil(t, err)\n\n\tcm.AssertExpectations(t)\n}\n\nfunc TestStepRunPrePost(t *testing.T) {\n\tctx := context.Background()\n\tsr := &stepRun{}\n\n\terr := sr.pre()(ctx)\n\tassert.Nil(t, err)\n\n\terr = sr.post()(ctx)\n\tassert.Nil(t, err)\n}\n"
  },
  {
    "path": "pkg/runner/step_test.go",
    "content": "package runner\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/nektos/act/pkg/common\"\n\t\"github.com/nektos/act/pkg/model\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/mock\"\n\tyaml \"gopkg.in/yaml.v3\"\n)\n\nfunc TestMergeIntoMap(t *testing.T) {\n\ttable := []struct {\n\t\tname     string\n\t\ttarget   map[string]string\n\t\tmaps     []map[string]string\n\t\texpected map[string]string\n\t}{\n\t\t{\n\t\t\tname:     \"testEmptyMap\",\n\t\t\ttarget:   map[string]string{},\n\t\t\tmaps:     []map[string]string{},\n\t\t\texpected: map[string]string{},\n\t\t},\n\t\t{\n\t\t\tname:   \"testMergeIntoEmptyMap\",\n\t\t\ttarget: map[string]string{},\n\t\t\tmaps: []map[string]string{\n\t\t\t\t{\n\t\t\t\t\t\"key1\": \"value1\",\n\t\t\t\t\t\"key2\": \"value2\",\n\t\t\t\t}, {\n\t\t\t\t\t\"key2\": \"overridden\",\n\t\t\t\t\t\"key3\": \"value3\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: map[string]string{\n\t\t\t\t\"key1\": \"value1\",\n\t\t\t\t\"key2\": \"overridden\",\n\t\t\t\t\"key3\": \"value3\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"testMergeIntoExistingMap\",\n\t\t\ttarget: map[string]string{\n\t\t\t\t\"key1\": \"value1\",\n\t\t\t\t\"key2\": \"value2\",\n\t\t\t},\n\t\t\tmaps: []map[string]string{\n\t\t\t\t{\n\t\t\t\t\t\"key1\": \"overridden\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: map[string]string{\n\t\t\t\t\"key1\": \"overridden\",\n\t\t\t\t\"key2\": \"value2\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range table {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tmergeIntoMapCaseSensitive(tt.target, tt.maps...)\n\t\t\tassert.Equal(t, tt.expected, tt.target)\n\t\t\tmergeIntoMapCaseInsensitive(tt.target, tt.maps...)\n\t\t\tassert.Equal(t, tt.expected, tt.target)\n\t\t})\n\t}\n}\n\ntype stepMock struct {\n\tmock.Mock\n\tstep\n}\n\nfunc (sm *stepMock) pre() common.Executor {\n\targs := sm.Called()\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (sm *stepMock) main() common.Executor {\n\targs := sm.Called()\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (sm *stepMock) post() common.Executor {\n\targs := sm.Called()\n\treturn args.Get(0).(func(context.Context) error)\n}\n\nfunc (sm *stepMock) getRunContext() *RunContext {\n\targs := sm.Called()\n\treturn args.Get(0).(*RunContext)\n}\n\nfunc (sm *stepMock) getGithubContext(ctx context.Context) *model.GithubContext {\n\targs := sm.Called()\n\treturn args.Get(0).(*RunContext).getGithubContext(ctx)\n}\n\nfunc (sm *stepMock) getStepModel() *model.Step {\n\targs := sm.Called()\n\treturn args.Get(0).(*model.Step)\n}\n\nfunc (sm *stepMock) getEnv() *map[string]string {\n\targs := sm.Called()\n\treturn args.Get(0).(*map[string]string)\n}\n\nfunc TestSetupEnv(t *testing.T) {\n\tcm := &containerMock{}\n\tsm := &stepMock{}\n\n\trc := &RunContext{\n\t\tConfig: &Config{\n\t\t\tEnv: map[string]string{\n\t\t\t\t\"GITHUB_RUN_ID\": \"runId\",\n\t\t\t},\n\t\t},\n\t\tRun: &model.Run{\n\t\t\tJobID: \"1\",\n\t\t\tWorkflow: &model.Workflow{\n\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\"1\": {\n\t\t\t\t\t\tEnv: yaml.Node{\n\t\t\t\t\t\t\tValue: \"JOB_KEY: jobvalue\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tEnv: map[string]string{\n\t\t\t\"RC_KEY\": \"rcvalue\",\n\t\t},\n\t\tJobContainer: cm,\n\t}\n\tstep := &model.Step{\n\t\tUses: \"./\",\n\t\tWith: map[string]string{\n\t\t\t\"STEP_WITH\": \"with-value\",\n\t\t},\n\t}\n\tenv := map[string]string{}\n\n\tsm.On(\"getRunContext\").Return(rc)\n\tsm.On(\"getGithubContext\").Return(rc)\n\tsm.On(\"getStepModel\").Return(step)\n\tsm.On(\"getEnv\").Return(&env)\n\n\terr := setupEnv(context.Background(), sm)\n\tassert.Nil(t, err)\n\n\t// These are commit or system specific\n\tdelete((env), \"GITHUB_REF\")\n\tdelete((env), \"GITHUB_REF_NAME\")\n\tdelete((env), \"GITHUB_REF_TYPE\")\n\tdelete((env), \"GITHUB_SHA\")\n\tdelete((env), \"GITHUB_WORKSPACE\")\n\tdelete((env), \"GITHUB_REPOSITORY\")\n\tdelete((env), \"GITHUB_REPOSITORY_OWNER\")\n\tdelete((env), \"GITHUB_ACTOR\")\n\n\tassert.Equal(t, map[string]string{\n\t\t\"ACT\":                      \"true\",\n\t\t\"CI\":                       \"true\",\n\t\t\"GITHUB_ACTION\":            \"\",\n\t\t\"GITHUB_ACTIONS\":           \"true\",\n\t\t\"GITHUB_ACTION_PATH\":       \"\",\n\t\t\"GITHUB_ACTION_REF\":        \"\",\n\t\t\"GITHUB_ACTION_REPOSITORY\": \"\",\n\t\t\"GITHUB_API_URL\":           \"https:///api/v3\",\n\t\t\"GITHUB_BASE_REF\":          \"\",\n\t\t\"GITHUB_EVENT_NAME\":        \"\",\n\t\t\"GITHUB_EVENT_PATH\":        \"/var/run/act/workflow/event.json\",\n\t\t\"GITHUB_GRAPHQL_URL\":       \"https:///api/graphql\",\n\t\t\"GITHUB_HEAD_REF\":          \"\",\n\t\t\"GITHUB_JOB\":               \"1\",\n\t\t\"GITHUB_RETENTION_DAYS\":    \"0\",\n\t\t\"GITHUB_RUN_ID\":            \"runId\",\n\t\t\"GITHUB_RUN_NUMBER\":        \"1\",\n\t\t\"GITHUB_RUN_ATTEMPT\":       \"1\",\n\t\t\"GITHUB_SERVER_URL\":        \"https://\",\n\t\t\"GITHUB_WORKFLOW\":          \"\",\n\t\t\"INPUT_STEP_WITH\":          \"with-value\",\n\t\t\"RC_KEY\":                   \"rcvalue\",\n\t\t\"RUNNER_PERFLOG\":           \"/dev/null\",\n\t\t\"RUNNER_TRACKING_ID\":       \"\",\n\t}, env)\n\n\tcm.AssertExpectations(t)\n}\n\nfunc TestIsStepEnabled(t *testing.T) {\n\tcreateTestStep := func(t *testing.T, input string) step {\n\t\tvar step *model.Step\n\t\terr := yaml.Unmarshal([]byte(input), &step)\n\t\tassert.NoError(t, err)\n\n\t\treturn &stepRun{\n\t\t\tRunContext: &RunContext{\n\t\t\t\tConfig: &Config{\n\t\t\t\t\tWorkdir: \".\",\n\t\t\t\t\tPlatforms: map[string]string{\n\t\t\t\t\t\t\"ubuntu-latest\": \"ubuntu-latest\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tStepResults: map[string]*model.StepResult{},\n\t\t\t\tEnv:         map[string]string{},\n\t\t\t\tRun: &model.Run{\n\t\t\t\t\tJobID: \"job1\",\n\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\tName: \"workflow1\",\n\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tStep: step,\n\t\t}\n\t}\n\n\tlog.SetLevel(log.DebugLevel)\n\tassertObject := assert.New(t)\n\n\t// success()\n\tstep := createTestStep(t, \"if: success()\")\n\tassertObject.True(isStepEnabled(context.Background(), step.getIfExpression(context.Background(), stepStageMain), step, stepStageMain))\n\n\tstep = createTestStep(t, \"if: success()\")\n\tstep.getRunContext().StepResults[\"a\"] = &model.StepResult{\n\t\tConclusion: model.StepStatusSuccess,\n\t}\n\tassertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain))\n\n\tstep = createTestStep(t, \"if: success()\")\n\tstep.getRunContext().StepResults[\"a\"] = &model.StepResult{\n\t\tConclusion: model.StepStatusFailure,\n\t}\n\tassertObject.False(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain))\n\n\t// failure()\n\tstep = createTestStep(t, \"if: failure()\")\n\tassertObject.False(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain))\n\n\tstep = createTestStep(t, \"if: failure()\")\n\tstep.getRunContext().StepResults[\"a\"] = &model.StepResult{\n\t\tConclusion: model.StepStatusSuccess,\n\t}\n\tassertObject.False(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain))\n\n\tstep = createTestStep(t, \"if: failure()\")\n\tstep.getRunContext().StepResults[\"a\"] = &model.StepResult{\n\t\tConclusion: model.StepStatusFailure,\n\t}\n\tassertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain))\n\n\t// always()\n\tstep = createTestStep(t, \"if: always()\")\n\tassertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain))\n\n\tstep = createTestStep(t, \"if: always()\")\n\tstep.getRunContext().StepResults[\"a\"] = &model.StepResult{\n\t\tConclusion: model.StepStatusSuccess,\n\t}\n\tassertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain))\n\n\tstep = createTestStep(t, \"if: always()\")\n\tstep.getRunContext().StepResults[\"a\"] = &model.StepResult{\n\t\tConclusion: model.StepStatusFailure,\n\t}\n\tassertObject.True(isStepEnabled(context.Background(), step.getStepModel().If.Value, step, stepStageMain))\n}\n\nfunc TestIsContinueOnError(t *testing.T) {\n\tcreateTestStep := func(t *testing.T, input string) step {\n\t\tvar step *model.Step\n\t\terr := yaml.Unmarshal([]byte(input), &step)\n\t\tassert.NoError(t, err)\n\n\t\treturn &stepRun{\n\t\t\tRunContext: &RunContext{\n\t\t\t\tConfig: &Config{\n\t\t\t\t\tWorkdir: \".\",\n\t\t\t\t\tPlatforms: map[string]string{\n\t\t\t\t\t\t\"ubuntu-latest\": \"ubuntu-latest\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tStepResults: map[string]*model.StepResult{},\n\t\t\t\tEnv:         map[string]string{},\n\t\t\t\tRun: &model.Run{\n\t\t\t\t\tJobID: \"job1\",\n\t\t\t\t\tWorkflow: &model.Workflow{\n\t\t\t\t\t\tName: \"workflow1\",\n\t\t\t\t\t\tJobs: map[string]*model.Job{\n\t\t\t\t\t\t\t\"job1\": createJob(t, `runs-on: ubuntu-latest`, \"\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tStep: step,\n\t\t}\n\t}\n\n\tlog.SetLevel(log.DebugLevel)\n\tassertObject := assert.New(t)\n\n\t// absent\n\tstep := createTestStep(t, \"name: test\")\n\tcontinueOnError, err := isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain)\n\tassertObject.False(continueOnError)\n\tassertObject.Nil(err)\n\n\t// explicit true\n\tstep = createTestStep(t, \"continue-on-error: true\")\n\tcontinueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain)\n\tassertObject.True(continueOnError)\n\tassertObject.Nil(err)\n\n\t// explicit false\n\tstep = createTestStep(t, \"continue-on-error: false\")\n\tcontinueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain)\n\tassertObject.False(continueOnError)\n\tassertObject.Nil(err)\n\n\t// expression true\n\tstep = createTestStep(t, \"continue-on-error: ${{ 'test' == 'test' }}\")\n\tcontinueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain)\n\tassertObject.True(continueOnError)\n\tassertObject.Nil(err)\n\n\t// expression false\n\tstep = createTestStep(t, \"continue-on-error: ${{ 'test' != 'test' }}\")\n\tcontinueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain)\n\tassertObject.False(continueOnError)\n\tassertObject.Nil(err)\n\n\t// expression parse error\n\tstep = createTestStep(t, \"continue-on-error: ${{ 'test' != test }}\")\n\tcontinueOnError, err = isContinueOnError(context.Background(), step.getStepModel().RawContinueOnError, step, stepStageMain)\n\tassertObject.False(continueOnError)\n\tassertObject.NotNil(err)\n}\n"
  },
  {
    "path": "pkg/runner/testdata/.github/workflows/local-reusable-and-dispatch.yml",
    "content": "name: reuse\n\non:\n  workflow_dispatch:\n    inputs:\n      my-val:\n        type: string\n        required: true\n        default: \"default_value_reuse_workflow_dispatch_call\"\n      dispatch-val:\n        type: string\n        default: \"I am a dispatch var for checking if I am being used in workflow_call\"\n\n  workflow_call:\n    inputs:\n      my-val:\n        type: string\n        required: true\n        default: \"default_value_reuse_workflow_call\"\n\njobs:\n  reusable_workflow_job:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - name: Run a one-line script\n        run: echo \"✅ 🚀 ✅ hello this is from workflow reuse. Value - \" ${{ inputs.my-val }} ${{ github.event_name }} ${{ inputs.dispatch-val }}\n      - name: Assert\n        run: |\n          exit ${{ ( inputs.my-val == 'default_value_reuse_workflow_call' || inputs.my-val == 'passed value from main' ) && !inputs.dispatch-val && '0' || '1' }}"
  },
  {
    "path": "pkg/runner/testdata/.github/workflows/local-reusable-workflow-no-inputs-array.yml",
    "content": "name: reusable\n\non:\n- workflow_call\n\njobs:\n  reusable_workflow_job:\n    runs-on: ubuntu-latest\n    steps:\n    - run: echo Test"
  },
  {
    "path": "pkg/runner/testdata/.github/workflows/local-reusable-workflow-no-inputs-string.yml",
    "content": "name: reusable\n\non: workflow_call\n\njobs:\n  reusable_workflow_job:\n    runs-on: ubuntu-latest\n    steps:\n    - run: echo Test"
  },
  {
    "path": "pkg/runner/testdata/.github/workflows/local-reusable-workflow.yml",
    "content": "name: reusable\n\non:\n  workflow_call:\n    inputs:\n      string_required:\n        required: true\n        type: string\n      string_optional:\n        required: false\n        type: string\n        default: string\n      bool_required:\n        required: true\n        type: boolean\n      bool_optional:\n        required: false\n        type: boolean\n        default: true\n      number_required:\n        required: true\n        type: number\n      number_optional:\n        required: false\n        type: number\n        default: ${{ 1 }}\n    outputs:\n      output:\n        description: \"A workflow output\"\n        value: ${{ jobs.reusable_workflow_job.outputs.job-output }}\n\njobs:\n  reusable_workflow_job:\n    runs-on: ubuntu-latest\n    steps:\n    - name: test required string\n      run: |\n        echo inputs.string_required=${{ inputs.string_required }}\n        [[ \"${{ inputs.string_required == 'string' }}\" = \"true\" ]] || exit 1\n\n    - name: test optional string\n      run: |\n        echo inputs.string_optional=${{ inputs.string_optional }}\n        [[ \"${{ inputs.string_optional == 'string' }}\" = \"true\" ]] || exit 1\n\n    - name: test required bool\n      run: |\n        echo inputs.bool_required=${{ tojson(inputs.bool_required) }}\n        [[ \"${{ tojson(inputs.bool_required) }}\" = \"true\" ]] || exit 1\n\n    - name: test optional bool\n      run: |\n        echo inputs.bool_optional=${{ tojson(inputs.bool_optional) }}\n        [[ \"${{ tojson(inputs.bool_optional) }}\" = \"true\" ]] || exit 1\n\n    - name: test required number\n      run: |\n        echo inputs.number_required=${{ tojson(inputs.number_required) }}\n        [[ \"${{ tojson(inputs.number_required) == '1' }}\" = \"true\" ]] || exit 1\n\n    - name: test optional number\n      run: |\n        echo inputs.number_optional=${{ tojson(inputs.number_optional) }}\n        [[ \"${{ tojson(inputs.number_optional) == '1' }}\" = \"true\" ]] || exit 1\n\n    - name: test secret\n      run: |\n        echo secrets.secret=${{ secrets.secret }}\n        [[ \"${{ secrets.secret == 'keep_it_private' }}\" = \"true\" ]] || exit 1\n\n    - name: test github.event_name is never workflow_call\n      run: |\n        echo github.event_name=${{ github.event_name }}\n        [[ \"${{ github.event_name != 'workflow_call' }}\" = \"true\" ]] || exit 1\n\n    - name: test output\n      id: output_test\n      run: |\n        echo \"value=${{ inputs.string_required }}\" >> $GITHUB_OUTPUT\n\n    outputs:\n      job-output: ${{ steps.output_test.outputs.value }}\n"
  },
  {
    "path": "pkg/runner/testdata/GITHUB_ENV-use-in-env-ctx/push.yml",
    "content": "on: push\njobs:\n  _:\n    runs-on: ubuntu-latest\n    env:\n      MYGLOBALENV3: myglobalval3\n    steps:\n    - run: |\n        echo MYGLOBALENV1=myglobalval1 > $GITHUB_ENV\n        echo \"::set-env name=MYGLOBALENV2::myglobalval2\"\n    - uses: nektos/act-test-actions/script@main\n      with:\n        main: |\n          env\n          [[ \"$MYGLOBALENV1\" = \"${{ env.MYGLOBALENV1 }}\" ]]\n          [[ \"$MYGLOBALENV1\" = \"${{ env.MYGLOBALENV1ALIAS }}\" ]]\n          [[ \"$MYGLOBALENV1\" = \"$MYGLOBALENV1ALIAS\" ]]\n          [[ \"$MYGLOBALENV2\" = \"${{ env.MYGLOBALENV2 }}\" ]]\n          [[ \"$MYGLOBALENV2\" = \"${{ env.MYGLOBALENV2ALIAS }}\" ]]\n          [[ \"$MYGLOBALENV2\" = \"$MYGLOBALENV2ALIAS\" ]]\n          [[ \"$MYGLOBALENV3\" = \"${{ env.MYGLOBALENV3 }}\" ]]\n          [[ \"$MYGLOBALENV3\" = \"${{ env.MYGLOBALENV3ALIAS }}\" ]]\n          [[ \"$MYGLOBALENV3\" = \"$MYGLOBALENV3ALIAS\" ]]\n      env:\n        MYGLOBALENV1ALIAS: ${{ env.MYGLOBALENV1 }}\n        MYGLOBALENV2ALIAS: ${{ env.MYGLOBALENV2 }}\n        MYGLOBALENV3ALIAS: ${{ env.MYGLOBALENV3 }}"
  },
  {
    "path": "pkg/runner/testdata/GITHUB_STATE/push.yml",
    "content": "on: push\njobs:\n  _:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: nektos/act-test-actions/script@main\n      with:\n        pre: |\n          env\n          echo mystate0=mystateval > $GITHUB_STATE\n          echo \"::save-state name=mystate1::mystateval\"\n        main: |\n          env\n          echo mystate2=mystateval > $GITHUB_STATE\n          echo \"::save-state name=mystate3::mystateval\"\n        post: |\n          env\n          [ \"$STATE_mystate0\" = \"mystateval\" ]\n          [ \"$STATE_mystate1\" = \"mystateval\" ]\n          [ \"$STATE_mystate2\" = \"mystateval\" ]\n          [ \"$STATE_mystate3\" = \"mystateval\" ]\n  test-id-collision-bug:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: nektos/act-test-actions/script@main\n      id: script\n      with:\n        pre: |\n          env\n          echo mystate0=mystateval > $GITHUB_STATE\n          echo \"::save-state name=mystate1::mystateval\"\n        main: |\n          env\n          echo mystate2=mystateval > $GITHUB_STATE\n          echo \"::save-state name=mystate3::mystateval\"\n        post: |\n          env\n          [ \"$STATE_mystate0\" = \"mystateval\" ]\n          [ \"$STATE_mystate1\" = \"mystateval\" ]\n          [ \"$STATE_mystate2\" = \"mystateval\" ]\n          [ \"$STATE_mystate3\" = \"mystateval\" ]\n    - uses: nektos/act-test-actions/script@main\n      id: pre-script\n      with:\n        main: |\n          env\n          echo mystate0=mystateerror > $GITHUB_STATE\n          echo \"::save-state name=mystate1::mystateerror\""
  },
  {
    "path": "pkg/runner/testdata/act-composite-env-test/action1/action.yml",
    "content": "name: action1\ndescription: action1\nruns:\n  using: composite\n  steps:\n  - name: env.COMPOSITE_OVERRIDE != '1'\n    run: exit 1\n    if: env.COMPOSITE_OVERRIDE != '1'\n    shell: bash\n  - name: env.JOB != '1'\n    run: exit 1\n    if: env.JOB != '1'\n    shell: bash\n  - name: env.GLOBAL != '1'\n    run: exit 1\n    if: env.GLOBAL != '1'\n    shell: bash\n  - uses: ./act-composite-env-test/action2\n    env:\n      COMPOSITE_OVERRIDE: \"2\"\n      COMPOSITE: \"1\"\n"
  },
  {
    "path": "pkg/runner/testdata/act-composite-env-test/action2/action.yml",
    "content": "name: action2\ndescription: actions2\nruns:\n  using: composite\n  steps:\n  - name: env.COMPOSITE_OVERRIDE != '2'\n    run: exit 1\n    if: env.COMPOSITE_OVERRIDE != '2'\n    shell: bash\n  - name: env.COMPOSITE != '1'\n    run: exit 1\n    if: env.COMPOSITE != '1'\n    shell: bash\n  - name: env.JOB != '1'\n    run: exit 1\n    if: env.JOB != '1'\n    shell: bash\n  - name: env.GLOBAL != '1'\n    run: exit 1\n    if: env.GLOBAL != '1'\n    shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/act-composite-env-test/push.yml",
    "content": "on: push\nenv:\n  GLOBAL: \"1\"\njobs:\n  test:\n    runs-on: ubuntu-latest\n    env:\n      JOB: \"1\"\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./act-composite-env-test/action1\n      env:\n        COMPOSITE_OVERRIDE: \"1\"\n"
  },
  {
    "path": "pkg/runner/testdata/action-cache-v2-fetch-failure-is-job-error/push.yml",
    "content": "name: basic\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: nektos/test-override@a\n"
  },
  {
    "path": "pkg/runner/testdata/actions/action1/Dockerfile",
    "content": "FROM ubuntu:18.04"
  },
  {
    "path": "pkg/runner/testdata/actions/action1/action.yml",
    "content": "name: 'action1'\nruns:\n  using: 'docker'\n  image: 'Dockerfile'\n"
  },
  {
    "path": "pkg/runner/testdata/actions/composite-fail-with-output/action.yml",
    "content": "outputs:\r\n  customoutput:\r\n    value: my-customoutput-${{ steps.random-color-generator.outputs.SELECTED_COLOR }}\r\nruns:\r\n  using: composite\r\n  steps:\r\n  - name: Set selected color\r\n    run: echo '::set-output name=SELECTED_COLOR::green'\r\n    id: random-color-generator\r\n    shell: bash\r\n  - name: fail\r\n    run: exit 1\r\n    shell: bash"
  },
  {
    "path": "pkg/runner/testdata/actions/docker-local/Dockerfile",
    "content": "# Container image that runs your code\nFROM node:16-buster-slim\n\n# Copies your code file from your action repository to the filesystem path `/` of the container\nCOPY entrypoint.sh /entrypoint.sh\n\n# Code file to execute when the docker container starts up (`entrypoint.sh`)\nENTRYPOINT [\"/entrypoint.sh\"]\n"
  },
  {
    "path": "pkg/runner/testdata/actions/docker-local/action.yml",
    "content": "name: 'Hello World'\ndescription: 'Greet someone and record the time'\ninputs:\n  who-to-greet:  # id of input\n    description: 'Who to greet'\n    required: true\n    default: 'World'\noutputs:\n  time: # id of output\n    description: 'The time we greeted you'\nruns:\n  using: 'docker'\n  image: 'Dockerfile'\n  env:\n    WHOAMI: ${{ inputs.who-to-greet }}\n  args:\n    - ${{ inputs.who-to-greet }}\n"
  },
  {
    "path": "pkg/runner/testdata/actions/docker-local/entrypoint.sh",
    "content": "#!/bin/sh -l\n\necho \"Hello $1\"\ntime=$(date)\necho ::set-output name=time::$time\necho ::set-output name=whoami::$WHOAMI\n\necho \"SOMEVAR=$1\" >>$GITHUB_ENV\n"
  },
  {
    "path": "pkg/runner/testdata/actions/docker-local-noargs/Dockerfile",
    "content": "# Container image that runs your code\nFROM node:12-buster-slim\n\n# Copies your code file from your action repository to the filesystem path `/` of the container\nCOPY entrypoint.sh /entrypoint.sh\n\n# Code file to execute when the docker container starts up (`entrypoint.sh`)\nENTRYPOINT [\"/entrypoint.sh\"]\n"
  },
  {
    "path": "pkg/runner/testdata/actions/docker-local-noargs/action.yml",
    "content": "name: 'Hello World'\ndescription: 'Greet someone and record the time'\ninputs:\n  who-to-greet:  # id of input\n    description: 'Who to greet'\n    required: true\n    default: 'World'\noutputs:\n  time: # id of output\n    description: 'The time we greeted you'\nruns:\n  using: 'docker'\n  image: 'Dockerfile'\n  env:\n    WHOAMI: ${{ inputs.who-to-greet }}"
  },
  {
    "path": "pkg/runner/testdata/actions/docker-local-noargs/entrypoint.sh",
    "content": "#!/bin/sh -l\n\necho \"Hello $1\"\ntime=$(date)\necho ::set-output name=time::$time\necho ::set-output name=whoami::$WHOAMI\n\necho \"SOMEVAR=$1\" >>$GITHUB_ENV\n"
  },
  {
    "path": "pkg/runner/testdata/actions/docker-url/action.yml",
    "content": "name: docker-url\nauthor: nektos\ndescription: testing\ninputs:\n  who-to-greet:\n    description: who to greet\n    required: true\n    default: World\nruns:\n  using: docker\n  image: docker://node:16-buster-slim\n  entrypoint: /bin/sh -c\n  env:\n    TEST: enabled\n  args:\n    - env\n"
  },
  {
    "path": "pkg/runner/testdata/actions/node12/README.md",
    "content": "### Updating\n\nIf an update to this app is required, it must be done manually via `npm run-script build` since the `node_modules` are not shared.\n"
  },
  {
    "path": "pkg/runner/testdata/actions/node12/action.yml",
    "content": "name: 'Hello World'\ndescription: 'Greet someone and record the time'\ninputs:\n  who-to-greet:  # id of input\n    description: 'Who to greet'\n    required: true\n    default: 'World'\noutputs:\n  time: # id of output\n    description: 'The time we greeted you'\nruns:\n  using: 'node12'\n  main: 'dist/index.js'"
  },
  {
    "path": "pkg/runner/testdata/actions/node12/dist/index.js",
    "content": "module.exports =\n/******/ (() => { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 932:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\nconst core = __webpack_require__(186);\nconst github = __webpack_require__(438);\n\ntry {\n  // `who-to-greet` input defined in action metadata file\n  const nameToGreet = core.getInput('who-to-greet');\n  console.log(`Hello ${nameToGreet}!`);\n  const time = (new Date()).toTimeString();\n  core.setOutput(\"time\", time);\n  // Get the JSON webhook payload for the event that triggered the workflow\n  const payload = JSON.stringify(github.context.payload, undefined, 2)\n  console.log(`The event payload: ${payload}`);\n} catch (error) {\n  core.setFailed(error.message);\n}\n\n/***/ }),\n\n/***/ 351:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n    result[\"default\"] = mod;\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst os = __importStar(__webpack_require__(87));\nconst utils_1 = __webpack_require__(278);\n/**\n * Commands\n *\n * Command Format:\n *   ::name key=value,key=value::message\n *\n * Examples:\n *   ::warning::This is the message\n *   ::set-env name=MY_VAR::some value\n */\nfunction issueCommand(command, properties, message) {\n    const cmd = new Command(command, properties, message);\n    process.stdout.write(cmd.toString() + os.EOL);\n}\nexports.issueCommand = issueCommand;\nfunction issue(name, message = '') {\n    issueCommand(name, {}, message);\n}\nexports.issue = issue;\nconst CMD_STRING = '::';\nclass Command {\n    constructor(command, properties, message) {\n        if (!command) {\n            command = 'missing.command';\n        }\n        this.command = command;\n        this.properties = properties;\n        this.message = message;\n    }\n    toString() {\n        let cmdStr = CMD_STRING + this.command;\n        if (this.properties && Object.keys(this.properties).length > 0) {\n            cmdStr += ' ';\n            let first = true;\n            for (const key in this.properties) {\n                if (this.properties.hasOwnProperty(key)) {\n                    const val = this.properties[key];\n                    if (val) {\n                        if (first) {\n                            first = false;\n                        }\n                        else {\n                            cmdStr += ',';\n                        }\n                        cmdStr += `${key}=${escapeProperty(val)}`;\n                    }\n                }\n            }\n        }\n        cmdStr += `${CMD_STRING}${escapeData(this.message)}`;\n        return cmdStr;\n    }\n}\nfunction escapeData(s) {\n    return utils_1.toCommandValue(s)\n        .replace(/%/g, '%25')\n        .replace(/\\r/g, '%0D')\n        .replace(/\\n/g, '%0A');\n}\nfunction escapeProperty(s) {\n    return utils_1.toCommandValue(s)\n        .replace(/%/g, '%25')\n        .replace(/\\r/g, '%0D')\n        .replace(/\\n/g, '%0A')\n        .replace(/:/g, '%3A')\n        .replace(/,/g, '%2C');\n}\n//# sourceMappingURL=command.js.map\n\n/***/ }),\n\n/***/ 186:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n    result[\"default\"] = mod;\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst command_1 = __webpack_require__(351);\nconst file_command_1 = __webpack_require__(717);\nconst utils_1 = __webpack_require__(278);\nconst os = __importStar(__webpack_require__(87));\nconst path = __importStar(__webpack_require__(622));\n/**\n * The code to exit an action\n */\nvar ExitCode;\n(function (ExitCode) {\n    /**\n     * A code indicating that the action was successful\n     */\n    ExitCode[ExitCode[\"Success\"] = 0] = \"Success\";\n    /**\n     * A code indicating that the action was a failure\n     */\n    ExitCode[ExitCode[\"Failure\"] = 1] = \"Failure\";\n})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));\n//-----------------------------------------------------------------------\n// Variables\n//-----------------------------------------------------------------------\n/**\n * Sets env variable for this action and future actions in the job\n * @param name the name of the variable to set\n * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction exportVariable(name, val) {\n    const convertedVal = utils_1.toCommandValue(val);\n    process.env[name] = convertedVal;\n    const filePath = process.env['GITHUB_ENV'] || '';\n    if (filePath) {\n        const delimiter = '_GitHubActionsFileCommandDelimeter_';\n        const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;\n        file_command_1.issueCommand('ENV', commandValue);\n    }\n    else {\n        command_1.issueCommand('set-env', { name }, convertedVal);\n    }\n}\nexports.exportVariable = exportVariable;\n/**\n * Registers a secret which will get masked from logs\n * @param secret value of the secret\n */\nfunction setSecret(secret) {\n    command_1.issueCommand('add-mask', {}, secret);\n}\nexports.setSecret = setSecret;\n/**\n * Prepends inputPath to the PATH (for this action and future actions)\n * @param inputPath\n */\nfunction addPath(inputPath) {\n    const filePath = process.env['GITHUB_PATH'] || '';\n    if (filePath) {\n        file_command_1.issueCommand('PATH', inputPath);\n    }\n    else {\n        command_1.issueCommand('add-path', {}, inputPath);\n    }\n    process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;\n}\nexports.addPath = addPath;\n/**\n * Gets the value of an input.  The value is also trimmed.\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   string\n */\nfunction getInput(name, options) {\n    const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';\n    if (options && options.required && !val) {\n        throw new Error(`Input required and not supplied: ${name}`);\n    }\n    return val.trim();\n}\nexports.getInput = getInput;\n/**\n * Sets the value of an output.\n *\n * @param     name     name of the output to set\n * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction setOutput(name, value) {\n    command_1.issueCommand('set-output', { name }, value);\n}\nexports.setOutput = setOutput;\n/**\n * Enables or disables the echoing of commands into stdout for the rest of the step.\n * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.\n *\n */\nfunction setCommandEcho(enabled) {\n    command_1.issue('echo', enabled ? 'on' : 'off');\n}\nexports.setCommandEcho = setCommandEcho;\n//-----------------------------------------------------------------------\n// Results\n//-----------------------------------------------------------------------\n/**\n * Sets the action status to failed.\n * When the action exits it will be with an exit code of 1\n * @param message add error issue message\n */\nfunction setFailed(message) {\n    process.exitCode = ExitCode.Failure;\n    error(message);\n}\nexports.setFailed = setFailed;\n//-----------------------------------------------------------------------\n// Logging Commands\n//-----------------------------------------------------------------------\n/**\n * Gets whether Actions Step Debug is on or not\n */\nfunction isDebug() {\n    return process.env['RUNNER_DEBUG'] === '1';\n}\nexports.isDebug = isDebug;\n/**\n * Writes debug message to user log\n * @param message debug message\n */\nfunction debug(message) {\n    command_1.issueCommand('debug', {}, message);\n}\nexports.debug = debug;\n/**\n * Adds an error issue\n * @param message error issue message. Errors will be converted to string via toString()\n */\nfunction error(message) {\n    command_1.issue('error', message instanceof Error ? message.toString() : message);\n}\nexports.error = error;\n/**\n * Adds an warning issue\n * @param message warning issue message. Errors will be converted to string via toString()\n */\nfunction warning(message) {\n    command_1.issue('warning', message instanceof Error ? message.toString() : message);\n}\nexports.warning = warning;\n/**\n * Writes info to log with console.log.\n * @param message info message\n */\nfunction info(message) {\n    process.stdout.write(message + os.EOL);\n}\nexports.info = info;\n/**\n * Begin an output group.\n *\n * Output until the next `groupEnd` will be foldable in this group\n *\n * @param name The name of the output group\n */\nfunction startGroup(name) {\n    command_1.issue('group', name);\n}\nexports.startGroup = startGroup;\n/**\n * End an output group.\n */\nfunction endGroup() {\n    command_1.issue('endgroup');\n}\nexports.endGroup = endGroup;\n/**\n * Wrap an asynchronous function call in a group.\n *\n * Returns the same type as the function itself.\n *\n * @param name The name of the group\n * @param fn The function to wrap in the group\n */\nfunction group(name, fn) {\n    return __awaiter(this, void 0, void 0, function* () {\n        startGroup(name);\n        let result;\n        try {\n            result = yield fn();\n        }\n        finally {\n            endGroup();\n        }\n        return result;\n    });\n}\nexports.group = group;\n//-----------------------------------------------------------------------\n// Wrapper action state\n//-----------------------------------------------------------------------\n/**\n * Saves state for current action, the state can only be retrieved by this action's post job execution.\n *\n * @param     name     name of the state to store\n * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction saveState(name, value) {\n    command_1.issueCommand('save-state', { name }, value);\n}\nexports.saveState = saveState;\n/**\n * Gets the value of an state set by this action's main execution.\n *\n * @param     name     name of the state to get\n * @returns   string\n */\nfunction getState(name) {\n    return process.env[`STATE_${name}`] || '';\n}\nexports.getState = getState;\n//# sourceMappingURL=core.js.map\n\n/***/ }),\n\n/***/ 717:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// For internal use, subject to change.\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\n    result[\"default\"] = mod;\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst fs = __importStar(__webpack_require__(747));\nconst os = __importStar(__webpack_require__(87));\nconst utils_1 = __webpack_require__(278);\nfunction issueCommand(command, message) {\n    const filePath = process.env[`GITHUB_${command}`];\n    if (!filePath) {\n        throw new Error(`Unable to find environment variable for file command ${command}`);\n    }\n    if (!fs.existsSync(filePath)) {\n        throw new Error(`Missing file at path: ${filePath}`);\n    }\n    fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {\n        encoding: 'utf8'\n    });\n}\nexports.issueCommand = issueCommand;\n//# sourceMappingURL=file-command.js.map\n\n/***/ }),\n\n/***/ 278:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n/**\n * Sanitizes an input into a string so it can be passed into issueCommand safely\n * @param input input to sanitize into a string\n */\nfunction toCommandValue(input) {\n    if (input === null || input === undefined) {\n        return '';\n    }\n    else if (typeof input === 'string' || input instanceof String) {\n        return input;\n    }\n    return JSON.stringify(input);\n}\nexports.toCommandValue = toCommandValue;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 53:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Context = void 0;\nconst fs_1 = __webpack_require__(747);\nconst os_1 = __webpack_require__(87);\nclass Context {\n    /**\n     * Hydrate the context from the environment\n     */\n    constructor() {\n        this.payload = {};\n        if (process.env.GITHUB_EVENT_PATH) {\n            if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) {\n                this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' }));\n            }\n            else {\n                const path = process.env.GITHUB_EVENT_PATH;\n                process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`);\n            }\n        }\n        this.eventName = process.env.GITHUB_EVENT_NAME;\n        this.sha = process.env.GITHUB_SHA;\n        this.ref = process.env.GITHUB_REF;\n        this.workflow = process.env.GITHUB_WORKFLOW;\n        this.action = process.env.GITHUB_ACTION;\n        this.actor = process.env.GITHUB_ACTOR;\n        this.job = process.env.GITHUB_JOB;\n        this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10);\n        this.runId = parseInt(process.env.GITHUB_RUN_ID, 10);\n    }\n    get issue() {\n        const payload = this.payload;\n        return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number });\n    }\n    get repo() {\n        if (process.env.GITHUB_REPOSITORY) {\n            const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');\n            return { owner, repo };\n        }\n        if (this.payload.repository) {\n            return {\n                owner: this.payload.repository.owner.login,\n                repo: this.payload.repository.name\n            };\n        }\n        throw new Error(\"context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'\");\n    }\n}\nexports.Context = Context;\n//# sourceMappingURL=context.js.map\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getOctokit = exports.context = void 0;\nconst Context = __importStar(__webpack_require__(53));\nconst utils_1 = __webpack_require__(30);\nexports.context = new Context.Context();\n/**\n * Returns a hydrated octokit ready to use for GitHub Actions\n *\n * @param     token    the repo PAT or GITHUB_TOKEN\n * @param     options  other options to set\n */\nfunction getOctokit(token, options) {\n    return new utils_1.GitHub(utils_1.getOctokitOptions(token, options));\n}\nexports.getOctokit = getOctokit;\n//# sourceMappingURL=github.js.map\n\n/***/ }),\n\n/***/ 914:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0;\nconst httpClient = __importStar(__webpack_require__(925));\nfunction getAuthString(token, options) {\n    if (!token && !options.auth) {\n        throw new Error('Parameter token or opts.auth is required');\n    }\n    else if (token && options.auth) {\n        throw new Error('Parameters token and opts.auth may not both be specified');\n    }\n    return typeof options.auth === 'string' ? options.auth : `token ${token}`;\n}\nexports.getAuthString = getAuthString;\nfunction getProxyAgent(destinationUrl) {\n    const hc = new httpClient.HttpClient();\n    return hc.getAgent(destinationUrl);\n}\nexports.getProxyAgent = getProxyAgent;\nfunction getApiBaseUrl() {\n    return process.env['GITHUB_API_URL'] || 'https://api.github.com';\n}\nexports.getApiBaseUrl = getApiBaseUrl;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 30:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getOctokitOptions = exports.GitHub = exports.context = void 0;\nconst Context = __importStar(__webpack_require__(53));\nconst Utils = __importStar(__webpack_require__(914));\n// octokit + plugins\nconst core_1 = __webpack_require__(762);\nconst plugin_rest_endpoint_methods_1 = __webpack_require__(44);\nconst plugin_paginate_rest_1 = __webpack_require__(193);\nexports.context = new Context.Context();\nconst baseUrl = Utils.getApiBaseUrl();\nconst defaults = {\n    baseUrl,\n    request: {\n        agent: Utils.getProxyAgent(baseUrl)\n    }\n};\nexports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(defaults);\n/**\n * Convience function to correctly format Octokit Options to pass into the constructor.\n *\n * @param     token    the repo PAT or GITHUB_TOKEN\n * @param     options  other options to set\n */\nfunction getOctokitOptions(token, options) {\n    const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller\n    // Auth\n    const auth = Utils.getAuthString(token, opts);\n    if (auth) {\n        opts.auth = auth;\n    }\n    return opts;\n}\nexports.getOctokitOptions = getOctokitOptions;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 925:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst url = __webpack_require__(835);\nconst http = __webpack_require__(605);\nconst https = __webpack_require__(211);\nconst pm = __webpack_require__(443);\nlet tunnel;\nvar HttpCodes;\n(function (HttpCodes) {\n    HttpCodes[HttpCodes[\"OK\"] = 200] = \"OK\";\n    HttpCodes[HttpCodes[\"MultipleChoices\"] = 300] = \"MultipleChoices\";\n    HttpCodes[HttpCodes[\"MovedPermanently\"] = 301] = \"MovedPermanently\";\n    HttpCodes[HttpCodes[\"ResourceMoved\"] = 302] = \"ResourceMoved\";\n    HttpCodes[HttpCodes[\"SeeOther\"] = 303] = \"SeeOther\";\n    HttpCodes[HttpCodes[\"NotModified\"] = 304] = \"NotModified\";\n    HttpCodes[HttpCodes[\"UseProxy\"] = 305] = \"UseProxy\";\n    HttpCodes[HttpCodes[\"SwitchProxy\"] = 306] = \"SwitchProxy\";\n    HttpCodes[HttpCodes[\"TemporaryRedirect\"] = 307] = \"TemporaryRedirect\";\n    HttpCodes[HttpCodes[\"PermanentRedirect\"] = 308] = \"PermanentRedirect\";\n    HttpCodes[HttpCodes[\"BadRequest\"] = 400] = \"BadRequest\";\n    HttpCodes[HttpCodes[\"Unauthorized\"] = 401] = \"Unauthorized\";\n    HttpCodes[HttpCodes[\"PaymentRequired\"] = 402] = \"PaymentRequired\";\n    HttpCodes[HttpCodes[\"Forbidden\"] = 403] = \"Forbidden\";\n    HttpCodes[HttpCodes[\"NotFound\"] = 404] = \"NotFound\";\n    HttpCodes[HttpCodes[\"MethodNotAllowed\"] = 405] = \"MethodNotAllowed\";\n    HttpCodes[HttpCodes[\"NotAcceptable\"] = 406] = \"NotAcceptable\";\n    HttpCodes[HttpCodes[\"ProxyAuthenticationRequired\"] = 407] = \"ProxyAuthenticationRequired\";\n    HttpCodes[HttpCodes[\"RequestTimeout\"] = 408] = \"RequestTimeout\";\n    HttpCodes[HttpCodes[\"Conflict\"] = 409] = \"Conflict\";\n    HttpCodes[HttpCodes[\"Gone\"] = 410] = \"Gone\";\n    HttpCodes[HttpCodes[\"TooManyRequests\"] = 429] = \"TooManyRequests\";\n    HttpCodes[HttpCodes[\"InternalServerError\"] = 500] = \"InternalServerError\";\n    HttpCodes[HttpCodes[\"NotImplemented\"] = 501] = \"NotImplemented\";\n    HttpCodes[HttpCodes[\"BadGateway\"] = 502] = \"BadGateway\";\n    HttpCodes[HttpCodes[\"ServiceUnavailable\"] = 503] = \"ServiceUnavailable\";\n    HttpCodes[HttpCodes[\"GatewayTimeout\"] = 504] = \"GatewayTimeout\";\n})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));\nvar Headers;\n(function (Headers) {\n    Headers[\"Accept\"] = \"accept\";\n    Headers[\"ContentType\"] = \"content-type\";\n})(Headers = exports.Headers || (exports.Headers = {}));\nvar MediaTypes;\n(function (MediaTypes) {\n    MediaTypes[\"ApplicationJson\"] = \"application/json\";\n})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {}));\n/**\n * Returns the proxy URL, depending upon the supplied url and proxy environment variables.\n * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com\n */\nfunction getProxyUrl(serverUrl) {\n    let proxyUrl = pm.getProxyUrl(url.parse(serverUrl));\n    return proxyUrl ? proxyUrl.href : '';\n}\nexports.getProxyUrl = getProxyUrl;\nconst HttpRedirectCodes = [\n    HttpCodes.MovedPermanently,\n    HttpCodes.ResourceMoved,\n    HttpCodes.SeeOther,\n    HttpCodes.TemporaryRedirect,\n    HttpCodes.PermanentRedirect\n];\nconst HttpResponseRetryCodes = [\n    HttpCodes.BadGateway,\n    HttpCodes.ServiceUnavailable,\n    HttpCodes.GatewayTimeout\n];\nconst RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];\nconst ExponentialBackoffCeiling = 10;\nconst ExponentialBackoffTimeSlice = 5;\nclass HttpClientResponse {\n    constructor(message) {\n        this.message = message;\n    }\n    readBody() {\n        return new Promise(async (resolve, reject) => {\n            let output = Buffer.alloc(0);\n            this.message.on('data', (chunk) => {\n                output = Buffer.concat([output, chunk]);\n            });\n            this.message.on('end', () => {\n                resolve(output.toString());\n            });\n        });\n    }\n}\nexports.HttpClientResponse = HttpClientResponse;\nfunction isHttps(requestUrl) {\n    let parsedUrl = url.parse(requestUrl);\n    return parsedUrl.protocol === 'https:';\n}\nexports.isHttps = isHttps;\nclass HttpClient {\n    constructor(userAgent, handlers, requestOptions) {\n        this._ignoreSslError = false;\n        this._allowRedirects = true;\n        this._allowRedirectDowngrade = false;\n        this._maxRedirects = 50;\n        this._allowRetries = false;\n        this._maxRetries = 1;\n        this._keepAlive = false;\n        this._disposed = false;\n        this.userAgent = userAgent;\n        this.handlers = handlers || [];\n        this.requestOptions = requestOptions;\n        if (requestOptions) {\n            if (requestOptions.ignoreSslError != null) {\n                this._ignoreSslError = requestOptions.ignoreSslError;\n            }\n            this._socketTimeout = requestOptions.socketTimeout;\n            if (requestOptions.allowRedirects != null) {\n                this._allowRedirects = requestOptions.allowRedirects;\n            }\n            if (requestOptions.allowRedirectDowngrade != null) {\n                this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade;\n            }\n            if (requestOptions.maxRedirects != null) {\n                this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);\n            }\n            if (requestOptions.keepAlive != null) {\n                this._keepAlive = requestOptions.keepAlive;\n            }\n            if (requestOptions.allowRetries != null) {\n                this._allowRetries = requestOptions.allowRetries;\n            }\n            if (requestOptions.maxRetries != null) {\n                this._maxRetries = requestOptions.maxRetries;\n            }\n        }\n    }\n    options(requestUrl, additionalHeaders) {\n        return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});\n    }\n    get(requestUrl, additionalHeaders) {\n        return this.request('GET', requestUrl, null, additionalHeaders || {});\n    }\n    del(requestUrl, additionalHeaders) {\n        return this.request('DELETE', requestUrl, null, additionalHeaders || {});\n    }\n    post(requestUrl, data, additionalHeaders) {\n        return this.request('POST', requestUrl, data, additionalHeaders || {});\n    }\n    patch(requestUrl, data, additionalHeaders) {\n        return this.request('PATCH', requestUrl, data, additionalHeaders || {});\n    }\n    put(requestUrl, data, additionalHeaders) {\n        return this.request('PUT', requestUrl, data, additionalHeaders || {});\n    }\n    head(requestUrl, additionalHeaders) {\n        return this.request('HEAD', requestUrl, null, additionalHeaders || {});\n    }\n    sendStream(verb, requestUrl, stream, additionalHeaders) {\n        return this.request(verb, requestUrl, stream, additionalHeaders);\n    }\n    /**\n     * Gets a typed object from an endpoint\n     * Be aware that not found returns a null.  Other errors (4xx, 5xx) reject the promise\n     */\n    async getJson(requestUrl, additionalHeaders = {}) {\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        let res = await this.get(requestUrl, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async postJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.post(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async putJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.put(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async patchJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.patch(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    /**\n     * Makes a raw http request.\n     * All other methods such as get, post, patch, and request ultimately call this.\n     * Prefer get, del, post and patch\n     */\n    async request(verb, requestUrl, data, headers) {\n        if (this._disposed) {\n            throw new Error('Client has already been disposed.');\n        }\n        let parsedUrl = url.parse(requestUrl);\n        let info = this._prepareRequest(verb, parsedUrl, headers);\n        // Only perform retries on reads since writes may not be idempotent.\n        let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1\n            ? this._maxRetries + 1\n            : 1;\n        let numTries = 0;\n        let response;\n        while (numTries < maxTries) {\n            response = await this.requestRaw(info, data);\n            // Check if it's an authentication challenge\n            if (response &&\n                response.message &&\n                response.message.statusCode === HttpCodes.Unauthorized) {\n                let authenticationHandler;\n                for (let i = 0; i < this.handlers.length; i++) {\n                    if (this.handlers[i].canHandleAuthentication(response)) {\n                        authenticationHandler = this.handlers[i];\n                        break;\n                    }\n                }\n                if (authenticationHandler) {\n                    return authenticationHandler.handleAuthentication(this, info, data);\n                }\n                else {\n                    // We have received an unauthorized response but have no handlers to handle it.\n                    // Let the response return to the caller.\n                    return response;\n                }\n            }\n            let redirectsRemaining = this._maxRedirects;\n            while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 &&\n                this._allowRedirects &&\n                redirectsRemaining > 0) {\n                const redirectUrl = response.message.headers['location'];\n                if (!redirectUrl) {\n                    // if there's no location to redirect to, we won't\n                    break;\n                }\n                let parsedRedirectUrl = url.parse(redirectUrl);\n                if (parsedUrl.protocol == 'https:' &&\n                    parsedUrl.protocol != parsedRedirectUrl.protocol &&\n                    !this._allowRedirectDowngrade) {\n                    throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');\n                }\n                // we need to finish reading the response before reassigning response\n                // which will leak the open socket.\n                await response.readBody();\n                // strip authorization header if redirected to a different hostname\n                if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {\n                    for (let header in headers) {\n                        // header names are case insensitive\n                        if (header.toLowerCase() === 'authorization') {\n                            delete headers[header];\n                        }\n                    }\n                }\n                // let's make the request with the new redirectUrl\n                info = this._prepareRequest(verb, parsedRedirectUrl, headers);\n                response = await this.requestRaw(info, data);\n                redirectsRemaining--;\n            }\n            if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) {\n                // If not a retry code, return immediately instead of retrying\n                return response;\n            }\n            numTries += 1;\n            if (numTries < maxTries) {\n                await response.readBody();\n                await this._performExponentialBackoff(numTries);\n            }\n        }\n        return response;\n    }\n    /**\n     * Needs to be called if keepAlive is set to true in request options.\n     */\n    dispose() {\n        if (this._agent) {\n            this._agent.destroy();\n        }\n        this._disposed = true;\n    }\n    /**\n     * Raw request.\n     * @param info\n     * @param data\n     */\n    requestRaw(info, data) {\n        return new Promise((resolve, reject) => {\n            let callbackForResult = function (err, res) {\n                if (err) {\n                    reject(err);\n                }\n                resolve(res);\n            };\n            this.requestRawWithCallback(info, data, callbackForResult);\n        });\n    }\n    /**\n     * Raw request with callback.\n     * @param info\n     * @param data\n     * @param onResult\n     */\n    requestRawWithCallback(info, data, onResult) {\n        let socket;\n        if (typeof data === 'string') {\n            info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');\n        }\n        let callbackCalled = false;\n        let handleResult = (err, res) => {\n            if (!callbackCalled) {\n                callbackCalled = true;\n                onResult(err, res);\n            }\n        };\n        let req = info.httpModule.request(info.options, (msg) => {\n            let res = new HttpClientResponse(msg);\n            handleResult(null, res);\n        });\n        req.on('socket', sock => {\n            socket = sock;\n        });\n        // If we ever get disconnected, we want the socket to timeout eventually\n        req.setTimeout(this._socketTimeout || 3 * 60000, () => {\n            if (socket) {\n                socket.end();\n            }\n            handleResult(new Error('Request timeout: ' + info.options.path), null);\n        });\n        req.on('error', function (err) {\n            // err has statusCode property\n            // res should have headers\n            handleResult(err, null);\n        });\n        if (data && typeof data === 'string') {\n            req.write(data, 'utf8');\n        }\n        if (data && typeof data !== 'string') {\n            data.on('close', function () {\n                req.end();\n            });\n            data.pipe(req);\n        }\n        else {\n            req.end();\n        }\n    }\n    /**\n     * Gets an http agent. This function is useful when you need an http agent that handles\n     * routing through a proxy server - depending upon the url and proxy environment variables.\n     * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com\n     */\n    getAgent(serverUrl) {\n        let parsedUrl = url.parse(serverUrl);\n        return this._getAgent(parsedUrl);\n    }\n    _prepareRequest(method, requestUrl, headers) {\n        const info = {};\n        info.parsedUrl = requestUrl;\n        const usingSsl = info.parsedUrl.protocol === 'https:';\n        info.httpModule = usingSsl ? https : http;\n        const defaultPort = usingSsl ? 443 : 80;\n        info.options = {};\n        info.options.host = info.parsedUrl.hostname;\n        info.options.port = info.parsedUrl.port\n            ? parseInt(info.parsedUrl.port)\n            : defaultPort;\n        info.options.path =\n            (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');\n        info.options.method = method;\n        info.options.headers = this._mergeHeaders(headers);\n        if (this.userAgent != null) {\n            info.options.headers['user-agent'] = this.userAgent;\n        }\n        info.options.agent = this._getAgent(info.parsedUrl);\n        // gives handlers an opportunity to participate\n        if (this.handlers) {\n            this.handlers.forEach(handler => {\n                handler.prepareRequest(info.options);\n            });\n        }\n        return info;\n    }\n    _mergeHeaders(headers) {\n        const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});\n        if (this.requestOptions && this.requestOptions.headers) {\n            return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));\n        }\n        return lowercaseKeys(headers || {});\n    }\n    _getExistingOrDefaultHeader(additionalHeaders, header, _default) {\n        const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});\n        let clientHeader;\n        if (this.requestOptions && this.requestOptions.headers) {\n            clientHeader = lowercaseKeys(this.requestOptions.headers)[header];\n        }\n        return additionalHeaders[header] || clientHeader || _default;\n    }\n    _getAgent(parsedUrl) {\n        let agent;\n        let proxyUrl = pm.getProxyUrl(parsedUrl);\n        let useProxy = proxyUrl && proxyUrl.hostname;\n        if (this._keepAlive && useProxy) {\n            agent = this._proxyAgent;\n        }\n        if (this._keepAlive && !useProxy) {\n            agent = this._agent;\n        }\n        // if agent is already assigned use that agent.\n        if (!!agent) {\n            return agent;\n        }\n        const usingSsl = parsedUrl.protocol === 'https:';\n        let maxSockets = 100;\n        if (!!this.requestOptions) {\n            maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;\n        }\n        if (useProxy) {\n            // If using proxy, need tunnel\n            if (!tunnel) {\n                tunnel = __webpack_require__(294);\n            }\n            const agentOptions = {\n                maxSockets: maxSockets,\n                keepAlive: this._keepAlive,\n                proxy: {\n                    proxyAuth: proxyUrl.auth,\n                    host: proxyUrl.hostname,\n                    port: proxyUrl.port\n                }\n            };\n            let tunnelAgent;\n            const overHttps = proxyUrl.protocol === 'https:';\n            if (usingSsl) {\n                tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;\n            }\n            else {\n                tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;\n            }\n            agent = tunnelAgent(agentOptions);\n            this._proxyAgent = agent;\n        }\n        // if reusing agent across request and tunneling agent isn't assigned create a new agent\n        if (this._keepAlive && !agent) {\n            const options = { keepAlive: this._keepAlive, maxSockets: maxSockets };\n            agent = usingSsl ? new https.Agent(options) : new http.Agent(options);\n            this._agent = agent;\n        }\n        // if not using private agent and tunnel agent isn't setup then use global agent\n        if (!agent) {\n            agent = usingSsl ? https.globalAgent : http.globalAgent;\n        }\n        if (usingSsl && this._ignoreSslError) {\n            // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process\n            // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options\n            // we have to cast it to any and change it directly\n            agent.options = Object.assign(agent.options || {}, {\n                rejectUnauthorized: false\n            });\n        }\n        return agent;\n    }\n    _performExponentialBackoff(retryNumber) {\n        retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);\n        const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);\n        return new Promise(resolve => setTimeout(() => resolve(), ms));\n    }\n    static dateTimeDeserializer(key, value) {\n        if (typeof value === 'string') {\n            let a = new Date(value);\n            if (!isNaN(a.valueOf())) {\n                return a;\n            }\n        }\n        return value;\n    }\n    async _processResponse(res, options) {\n        return new Promise(async (resolve, reject) => {\n            const statusCode = res.message.statusCode;\n            const response = {\n                statusCode: statusCode,\n                result: null,\n                headers: {}\n            };\n            // not found leads to null obj returned\n            if (statusCode == HttpCodes.NotFound) {\n                resolve(response);\n            }\n            let obj;\n            let contents;\n            // get the result from the body\n            try {\n                contents = await res.readBody();\n                if (contents && contents.length > 0) {\n                    if (options && options.deserializeDates) {\n                        obj = JSON.parse(contents, HttpClient.dateTimeDeserializer);\n                    }\n                    else {\n                        obj = JSON.parse(contents);\n                    }\n                    response.result = obj;\n                }\n                response.headers = res.message.headers;\n            }\n            catch (err) {\n                // Invalid resource (contents not json);  leaving result obj null\n            }\n            // note that 3xx redirects are handled by the http layer.\n            if (statusCode > 299) {\n                let msg;\n                // if exception/error in body, attempt to get better error\n                if (obj && obj.message) {\n                    msg = obj.message;\n                }\n                else if (contents && contents.length > 0) {\n                    // it may be the case that the exception is in the body message as string\n                    msg = contents;\n                }\n                else {\n                    msg = 'Failed request: (' + statusCode + ')';\n                }\n                let err = new Error(msg);\n                // attach statusCode and body obj (if available) to the error object\n                err['statusCode'] = statusCode;\n                if (response.result) {\n                    err['result'] = response.result;\n                }\n                reject(err);\n            }\n            else {\n                resolve(response);\n            }\n        });\n    }\n}\nexports.HttpClient = HttpClient;\n\n\n/***/ }),\n\n/***/ 443:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst url = __webpack_require__(835);\nfunction getProxyUrl(reqUrl) {\n    let usingSsl = reqUrl.protocol === 'https:';\n    let proxyUrl;\n    if (checkBypass(reqUrl)) {\n        return proxyUrl;\n    }\n    let proxyVar;\n    if (usingSsl) {\n        proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY'];\n    }\n    else {\n        proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY'];\n    }\n    if (proxyVar) {\n        proxyUrl = url.parse(proxyVar);\n    }\n    return proxyUrl;\n}\nexports.getProxyUrl = getProxyUrl;\nfunction checkBypass(reqUrl) {\n    if (!reqUrl.hostname) {\n        return false;\n    }\n    let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';\n    if (!noProxy) {\n        return false;\n    }\n    // Determine the request port\n    let reqPort;\n    if (reqUrl.port) {\n        reqPort = Number(reqUrl.port);\n    }\n    else if (reqUrl.protocol === 'http:') {\n        reqPort = 80;\n    }\n    else if (reqUrl.protocol === 'https:') {\n        reqPort = 443;\n    }\n    // Format the request hostname and hostname with port\n    let upperReqHosts = [reqUrl.hostname.toUpperCase()];\n    if (typeof reqPort === 'number') {\n        upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);\n    }\n    // Compare request host against noproxy\n    for (let upperNoProxyItem of noProxy\n        .split(',')\n        .map(x => x.trim().toUpperCase())\n        .filter(x => x)) {\n        if (upperReqHosts.some(x => x === upperNoProxyItem)) {\n            return true;\n        }\n    }\n    return false;\n}\nexports.checkBypass = checkBypass;\n\n\n/***/ }),\n\n/***/ 334:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nasync function auth(token) {\n  const tokenType = token.split(/\\./).length === 3 ? \"app\" : /^v\\d+\\./.test(token) ? \"installation\" : \"oauth\";\n  return {\n    type: \"token\",\n    token: token,\n    tokenType\n  };\n}\n\n/**\n * Prefix token for usage in the Authorization header\n *\n * @param token OAuth token or JSON Web Token\n */\nfunction withAuthorizationPrefix(token) {\n  if (token.split(/\\./).length === 3) {\n    return `bearer ${token}`;\n  }\n\n  return `token ${token}`;\n}\n\nasync function hook(token, request, route, parameters) {\n  const endpoint = request.endpoint.merge(route, parameters);\n  endpoint.headers.authorization = withAuthorizationPrefix(token);\n  return request(endpoint);\n}\n\nconst createTokenAuth = function createTokenAuth(token) {\n  if (!token) {\n    throw new Error(\"[@octokit/auth-token] No token passed to createTokenAuth\");\n  }\n\n  if (typeof token !== \"string\") {\n    throw new Error(\"[@octokit/auth-token] Token passed to createTokenAuth is not a string\");\n  }\n\n  token = token.replace(/^(token|bearer) +/i, \"\");\n  return Object.assign(auth.bind(null, token), {\n    hook: hook.bind(null, token)\n  });\n};\n\nexports.createTokenAuth = createTokenAuth;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 762:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar universalUserAgent = __webpack_require__(429);\nvar beforeAfterHook = __webpack_require__(682);\nvar request = __webpack_require__(234);\nvar graphql = __webpack_require__(668);\nvar authToken = __webpack_require__(334);\n\nfunction _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\nfunction ownKeys(object, enumerableOnly) {\n  var keys = Object.keys(object);\n\n  if (Object.getOwnPropertySymbols) {\n    var symbols = Object.getOwnPropertySymbols(object);\n    if (enumerableOnly) symbols = symbols.filter(function (sym) {\n      return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n    });\n    keys.push.apply(keys, symbols);\n  }\n\n  return keys;\n}\n\nfunction _objectSpread2(target) {\n  for (var i = 1; i < arguments.length; i++) {\n    var source = arguments[i] != null ? arguments[i] : {};\n\n    if (i % 2) {\n      ownKeys(Object(source), true).forEach(function (key) {\n        _defineProperty(target, key, source[key]);\n      });\n    } else if (Object.getOwnPropertyDescriptors) {\n      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n    } else {\n      ownKeys(Object(source)).forEach(function (key) {\n        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n      });\n    }\n  }\n\n  return target;\n}\n\nconst VERSION = \"3.1.2\";\n\nclass Octokit {\n  constructor(options = {}) {\n    const hook = new beforeAfterHook.Collection();\n    const requestDefaults = {\n      baseUrl: request.request.endpoint.DEFAULTS.baseUrl,\n      headers: {},\n      request: Object.assign({}, options.request, {\n        hook: hook.bind(null, \"request\")\n      }),\n      mediaType: {\n        previews: [],\n        format: \"\"\n      }\n    }; // prepend default user agent with `options.userAgent` if set\n\n    requestDefaults.headers[\"user-agent\"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(\" \");\n\n    if (options.baseUrl) {\n      requestDefaults.baseUrl = options.baseUrl;\n    }\n\n    if (options.previews) {\n      requestDefaults.mediaType.previews = options.previews;\n    }\n\n    if (options.timeZone) {\n      requestDefaults.headers[\"time-zone\"] = options.timeZone;\n    }\n\n    this.request = request.request.defaults(requestDefaults);\n    this.graphql = graphql.withCustomRequest(this.request).defaults(_objectSpread2(_objectSpread2({}, requestDefaults), {}, {\n      baseUrl: requestDefaults.baseUrl.replace(/\\/api\\/v3$/, \"/api\")\n    }));\n    this.log = Object.assign({\n      debug: () => {},\n      info: () => {},\n      warn: console.warn.bind(console),\n      error: console.error.bind(console)\n    }, options.log);\n    this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance\n    //     is unauthenticated. The `this.auth()` method is a no-op and no request hook is registred.\n    // (2) If only `options.auth` is set, use the default token authentication strategy.\n    // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance.\n    // TODO: type `options.auth` based on `options.authStrategy`.\n\n    if (!options.authStrategy) {\n      if (!options.auth) {\n        // (1)\n        this.auth = async () => ({\n          type: \"unauthenticated\"\n        });\n      } else {\n        // (2)\n        const auth = authToken.createTokenAuth(options.auth); // @ts-ignore  ¯\\_(ツ)_/¯\n\n        hook.wrap(\"request\", auth.hook);\n        this.auth = auth;\n      }\n    } else {\n      const auth = options.authStrategy(Object.assign({\n        request: this.request\n      }, options.auth)); // @ts-ignore  ¯\\_(ツ)_/¯\n\n      hook.wrap(\"request\", auth.hook);\n      this.auth = auth;\n    } // apply plugins\n    // https://stackoverflow.com/a/16345172\n\n\n    const classConstructor = this.constructor;\n    classConstructor.plugins.forEach(plugin => {\n      Object.assign(this, plugin(this, options));\n    });\n  }\n\n  static defaults(defaults) {\n    const OctokitWithDefaults = class extends this {\n      constructor(...args) {\n        const options = args[0] || {};\n\n        if (typeof defaults === \"function\") {\n          super(defaults(options));\n          return;\n        }\n\n        super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? {\n          userAgent: `${options.userAgent} ${defaults.userAgent}`\n        } : null));\n      }\n\n    };\n    return OctokitWithDefaults;\n  }\n  /**\n   * Attach a plugin (or many) to your Octokit instance.\n   *\n   * @example\n   * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...)\n   */\n\n\n  static plugin(...newPlugins) {\n    var _a;\n\n    const currentPlugins = this.plugins;\n    const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a);\n    return NewOctokit;\n  }\n\n}\nOctokit.VERSION = VERSION;\nOctokit.plugins = [];\n\nexports.Octokit = Octokit;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 440:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar isPlainObject = __webpack_require__(287);\nvar universalUserAgent = __webpack_require__(429);\n\nfunction lowercaseKeys(object) {\n  if (!object) {\n    return {};\n  }\n\n  return Object.keys(object).reduce((newObj, key) => {\n    newObj[key.toLowerCase()] = object[key];\n    return newObj;\n  }, {});\n}\n\nfunction mergeDeep(defaults, options) {\n  const result = Object.assign({}, defaults);\n  Object.keys(options).forEach(key => {\n    if (isPlainObject.isPlainObject(options[key])) {\n      if (!(key in defaults)) Object.assign(result, {\n        [key]: options[key]\n      });else result[key] = mergeDeep(defaults[key], options[key]);\n    } else {\n      Object.assign(result, {\n        [key]: options[key]\n      });\n    }\n  });\n  return result;\n}\n\nfunction merge(defaults, route, options) {\n  if (typeof route === \"string\") {\n    let [method, url] = route.split(\" \");\n    options = Object.assign(url ? {\n      method,\n      url\n    } : {\n      url: method\n    }, options);\n  } else {\n    options = Object.assign({}, route);\n  } // lowercase header names before merging with defaults to avoid duplicates\n\n\n  options.headers = lowercaseKeys(options.headers);\n  const mergedOptions = mergeDeep(defaults || {}, options); // mediaType.previews arrays are merged, instead of overwritten\n\n  if (defaults && defaults.mediaType.previews.length) {\n    mergedOptions.mediaType.previews = defaults.mediaType.previews.filter(preview => !mergedOptions.mediaType.previews.includes(preview)).concat(mergedOptions.mediaType.previews);\n  }\n\n  mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, \"\"));\n  return mergedOptions;\n}\n\nfunction addQueryParameters(url, parameters) {\n  const separator = /\\?/.test(url) ? \"&\" : \"?\";\n  const names = Object.keys(parameters);\n\n  if (names.length === 0) {\n    return url;\n  }\n\n  return url + separator + names.map(name => {\n    if (name === \"q\") {\n      return \"q=\" + parameters.q.split(\"+\").map(encodeURIComponent).join(\"+\");\n    }\n\n    return `${name}=${encodeURIComponent(parameters[name])}`;\n  }).join(\"&\");\n}\n\nconst urlVariableRegex = /\\{[^}]+\\}/g;\n\nfunction removeNonChars(variableName) {\n  return variableName.replace(/^\\W+|\\W+$/g, \"\").split(/,/);\n}\n\nfunction extractUrlVariableNames(url) {\n  const matches = url.match(urlVariableRegex);\n\n  if (!matches) {\n    return [];\n  }\n\n  return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);\n}\n\nfunction omit(object, keysToOmit) {\n  return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => {\n    obj[key] = object[key];\n    return obj;\n  }, {});\n}\n\n// Based on https://github.com/bramstein/url-template, licensed under BSD\n// TODO: create separate package.\n//\n// Copyright (c) 2012-2014, Bram Stein\n// All rights reserved.\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//  1. Redistributions of source code must retain the above copyright\n//     notice, this list of conditions and the following disclaimer.\n//  2. Redistributions in binary form must reproduce the above copyright\n//     notice, this list of conditions and the following disclaimer in the\n//     documentation and/or other materials provided with the distribution.\n//  3. The name of the author may not be used to endorse or promote products\n//     derived from this software without specific prior written permission.\n// THIS SOFTWARE IS PROVIDED BY THE AUTHOR \"AS IS\" AND ANY EXPRESS OR IMPLIED\n// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n// EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n/* istanbul ignore file */\nfunction encodeReserved(str) {\n  return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) {\n    if (!/%[0-9A-Fa-f]/.test(part)) {\n      part = encodeURI(part).replace(/%5B/g, \"[\").replace(/%5D/g, \"]\");\n    }\n\n    return part;\n  }).join(\"\");\n}\n\nfunction encodeUnreserved(str) {\n  return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {\n    return \"%\" + c.charCodeAt(0).toString(16).toUpperCase();\n  });\n}\n\nfunction encodeValue(operator, value, key) {\n  value = operator === \"+\" || operator === \"#\" ? encodeReserved(value) : encodeUnreserved(value);\n\n  if (key) {\n    return encodeUnreserved(key) + \"=\" + value;\n  } else {\n    return value;\n  }\n}\n\nfunction isDefined(value) {\n  return value !== undefined && value !== null;\n}\n\nfunction isKeyOperator(operator) {\n  return operator === \";\" || operator === \"&\" || operator === \"?\";\n}\n\nfunction getValues(context, operator, key, modifier) {\n  var value = context[key],\n      result = [];\n\n  if (isDefined(value) && value !== \"\") {\n    if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n      value = value.toString();\n\n      if (modifier && modifier !== \"*\") {\n        value = value.substring(0, parseInt(modifier, 10));\n      }\n\n      result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : \"\"));\n    } else {\n      if (modifier === \"*\") {\n        if (Array.isArray(value)) {\n          value.filter(isDefined).forEach(function (value) {\n            result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : \"\"));\n          });\n        } else {\n          Object.keys(value).forEach(function (k) {\n            if (isDefined(value[k])) {\n              result.push(encodeValue(operator, value[k], k));\n            }\n          });\n        }\n      } else {\n        const tmp = [];\n\n        if (Array.isArray(value)) {\n          value.filter(isDefined).forEach(function (value) {\n            tmp.push(encodeValue(operator, value));\n          });\n        } else {\n          Object.keys(value).forEach(function (k) {\n            if (isDefined(value[k])) {\n              tmp.push(encodeUnreserved(k));\n              tmp.push(encodeValue(operator, value[k].toString()));\n            }\n          });\n        }\n\n        if (isKeyOperator(operator)) {\n          result.push(encodeUnreserved(key) + \"=\" + tmp.join(\",\"));\n        } else if (tmp.length !== 0) {\n          result.push(tmp.join(\",\"));\n        }\n      }\n    }\n  } else {\n    if (operator === \";\") {\n      if (isDefined(value)) {\n        result.push(encodeUnreserved(key));\n      }\n    } else if (value === \"\" && (operator === \"&\" || operator === \"?\")) {\n      result.push(encodeUnreserved(key) + \"=\");\n    } else if (value === \"\") {\n      result.push(\"\");\n    }\n  }\n\n  return result;\n}\n\nfunction parseUrl(template) {\n  return {\n    expand: expand.bind(null, template)\n  };\n}\n\nfunction expand(template, context) {\n  var operators = [\"+\", \"#\", \".\", \"/\", \";\", \"?\", \"&\"];\n  return template.replace(/\\{([^\\{\\}]+)\\}|([^\\{\\}]+)/g, function (_, expression, literal) {\n    if (expression) {\n      let operator = \"\";\n      const values = [];\n\n      if (operators.indexOf(expression.charAt(0)) !== -1) {\n        operator = expression.charAt(0);\n        expression = expression.substr(1);\n      }\n\n      expression.split(/,/g).forEach(function (variable) {\n        var tmp = /([^:\\*]*)(?::(\\d+)|(\\*))?/.exec(variable);\n        values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3]));\n      });\n\n      if (operator && operator !== \"+\") {\n        var separator = \",\";\n\n        if (operator === \"?\") {\n          separator = \"&\";\n        } else if (operator !== \"#\") {\n          separator = operator;\n        }\n\n        return (values.length !== 0 ? operator : \"\") + values.join(separator);\n      } else {\n        return values.join(\",\");\n      }\n    } else {\n      return encodeReserved(literal);\n    }\n  });\n}\n\nfunction parse(options) {\n  // https://fetch.spec.whatwg.org/#methods\n  let method = options.method.toUpperCase(); // replace :varname with {varname} to make it RFC 6570 compatible\n\n  let url = (options.url || \"/\").replace(/:([a-z]\\w+)/g, \"{+$1}\");\n  let headers = Object.assign({}, options.headers);\n  let body;\n  let parameters = omit(options, [\"method\", \"baseUrl\", \"url\", \"headers\", \"request\", \"mediaType\"]); // extract variable names from URL to calculate remaining variables later\n\n  const urlVariableNames = extractUrlVariableNames(url);\n  url = parseUrl(url).expand(parameters);\n\n  if (!/^http/.test(url)) {\n    url = options.baseUrl + url;\n  }\n\n  const omittedParameters = Object.keys(options).filter(option => urlVariableNames.includes(option)).concat(\"baseUrl\");\n  const remainingParameters = omit(parameters, omittedParameters);\n  const isBinaryRequest = /application\\/octet-stream/i.test(headers.accept);\n\n  if (!isBinaryRequest) {\n    if (options.mediaType.format) {\n      // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw\n      headers.accept = headers.accept.split(/,/).map(preview => preview.replace(/application\\/vnd(\\.\\w+)(\\.v3)?(\\.\\w+)?(\\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`)).join(\",\");\n    }\n\n    if (options.mediaType.previews.length) {\n      const previewsFromAcceptHeader = headers.accept.match(/[\\w-]+(?=-preview)/g) || [];\n      headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map(preview => {\n        const format = options.mediaType.format ? `.${options.mediaType.format}` : \"+json\";\n        return `application/vnd.github.${preview}-preview${format}`;\n      }).join(\",\");\n    }\n  } // for GET/HEAD requests, set URL query parameters from remaining parameters\n  // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters\n\n\n  if ([\"GET\", \"HEAD\"].includes(method)) {\n    url = addQueryParameters(url, remainingParameters);\n  } else {\n    if (\"data\" in remainingParameters) {\n      body = remainingParameters.data;\n    } else {\n      if (Object.keys(remainingParameters).length) {\n        body = remainingParameters;\n      } else {\n        headers[\"content-length\"] = 0;\n      }\n    }\n  } // default content-type for JSON if body is set\n\n\n  if (!headers[\"content-type\"] && typeof body !== \"undefined\") {\n    headers[\"content-type\"] = \"application/json; charset=utf-8\";\n  } // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.\n  // fetch does not allow to set `content-length` header, but we can set body to an empty string\n\n\n  if ([\"PATCH\", \"PUT\"].includes(method) && typeof body === \"undefined\") {\n    body = \"\";\n  } // Only return body/request keys if present\n\n\n  return Object.assign({\n    method,\n    url,\n    headers\n  }, typeof body !== \"undefined\" ? {\n    body\n  } : null, options.request ? {\n    request: options.request\n  } : null);\n}\n\nfunction endpointWithDefaults(defaults, route, options) {\n  return parse(merge(defaults, route, options));\n}\n\nfunction withDefaults(oldDefaults, newDefaults) {\n  const DEFAULTS = merge(oldDefaults, newDefaults);\n  const endpoint = endpointWithDefaults.bind(null, DEFAULTS);\n  return Object.assign(endpoint, {\n    DEFAULTS,\n    defaults: withDefaults.bind(null, DEFAULTS),\n    merge: merge.bind(null, DEFAULTS),\n    parse\n  });\n}\n\nconst VERSION = \"6.0.6\";\n\nconst userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`; // DEFAULTS has all properties set that EndpointOptions has, except url.\n// So we use RequestParameters and add method as additional required property.\n\nconst DEFAULTS = {\n  method: \"GET\",\n  baseUrl: \"https://api.github.com\",\n  headers: {\n    accept: \"application/vnd.github.v3+json\",\n    \"user-agent\": userAgent\n  },\n  mediaType: {\n    format: \"\",\n    previews: []\n  }\n};\n\nconst endpoint = withDefaults(null, DEFAULTS);\n\nexports.endpoint = endpoint;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 668:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar request = __webpack_require__(234);\nvar universalUserAgent = __webpack_require__(429);\n\nconst VERSION = \"4.5.6\";\n\nclass GraphqlError extends Error {\n  constructor(request, response) {\n    const message = response.data.errors[0].message;\n    super(message);\n    Object.assign(this, response.data);\n    Object.assign(this, {\n      headers: response.headers\n    });\n    this.name = \"GraphqlError\";\n    this.request = request; // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n  }\n\n}\n\nconst NON_VARIABLE_OPTIONS = [\"method\", \"baseUrl\", \"url\", \"headers\", \"request\", \"query\", \"mediaType\"];\nconst GHES_V3_SUFFIX_REGEX = /\\/api\\/v3\\/?$/;\nfunction graphql(request, query, options) {\n  if (typeof query === \"string\" && options && \"query\" in options) {\n    return Promise.reject(new Error(`[@octokit/graphql] \"query\" cannot be used as variable name`));\n  }\n\n  const parsedOptions = typeof query === \"string\" ? Object.assign({\n    query\n  }, options) : query;\n  const requestOptions = Object.keys(parsedOptions).reduce((result, key) => {\n    if (NON_VARIABLE_OPTIONS.includes(key)) {\n      result[key] = parsedOptions[key];\n      return result;\n    }\n\n    if (!result.variables) {\n      result.variables = {};\n    }\n\n    result.variables[key] = parsedOptions[key];\n    return result;\n  }, {}); // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix\n  // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451\n\n  const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;\n\n  if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {\n    requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, \"/api/graphql\");\n  }\n\n  return request(requestOptions).then(response => {\n    if (response.data.errors) {\n      const headers = {};\n\n      for (const key of Object.keys(response.headers)) {\n        headers[key] = response.headers[key];\n      }\n\n      throw new GraphqlError(requestOptions, {\n        headers,\n        data: response.data\n      });\n    }\n\n    return response.data.data;\n  });\n}\n\nfunction withDefaults(request$1, newDefaults) {\n  const newRequest = request$1.defaults(newDefaults);\n\n  const newApi = (query, options) => {\n    return graphql(newRequest, query, options);\n  };\n\n  return Object.assign(newApi, {\n    defaults: withDefaults.bind(null, newRequest),\n    endpoint: request.request.endpoint\n  });\n}\n\nconst graphql$1 = withDefaults(request.request, {\n  headers: {\n    \"user-agent\": `octokit-graphql.js/${VERSION} ${universalUserAgent.getUserAgent()}`\n  },\n  method: \"POST\",\n  url: \"/graphql\"\n});\nfunction withCustomRequest(customRequest) {\n  return withDefaults(customRequest, {\n    method: \"POST\",\n    url: \"/graphql\"\n  });\n}\n\nexports.graphql = graphql$1;\nexports.withCustomRequest = withCustomRequest;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 193:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nconst VERSION = \"2.4.0\";\n\n/**\n * Some “list” response that can be paginated have a different response structure\n *\n * They have a `total_count` key in the response (search also has `incomplete_results`,\n * /installation/repositories also has `repository_selection`), as well as a key with\n * the list of the items which name varies from endpoint to endpoint.\n *\n * Octokit normalizes these responses so that paginated results are always returned following\n * the same structure. One challenge is that if the list response has only one page, no Link\n * header is provided, so this header alone is not sufficient to check wether a response is\n * paginated or not.\n *\n * We check if a \"total_count\" key is present in the response data, but also make sure that\n * a \"url\" property is not, as the \"Get the combined status for a specific ref\" endpoint would\n * otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref\n */\nfunction normalizePaginatedListResponse(response) {\n  const responseNeedsNormalization = \"total_count\" in response.data && !(\"url\" in response.data);\n  if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way\n  // to retrieve the same information.\n\n  const incompleteResults = response.data.incomplete_results;\n  const repositorySelection = response.data.repository_selection;\n  const totalCount = response.data.total_count;\n  delete response.data.incomplete_results;\n  delete response.data.repository_selection;\n  delete response.data.total_count;\n  const namespaceKey = Object.keys(response.data)[0];\n  const data = response.data[namespaceKey];\n  response.data = data;\n\n  if (typeof incompleteResults !== \"undefined\") {\n    response.data.incomplete_results = incompleteResults;\n  }\n\n  if (typeof repositorySelection !== \"undefined\") {\n    response.data.repository_selection = repositorySelection;\n  }\n\n  response.data.total_count = totalCount;\n  return response;\n}\n\nfunction iterator(octokit, route, parameters) {\n  const options = typeof route === \"function\" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters);\n  const requestMethod = typeof route === \"function\" ? route : octokit.request;\n  const method = options.method;\n  const headers = options.headers;\n  let url = options.url;\n  return {\n    [Symbol.asyncIterator]: () => ({\n      next() {\n        if (!url) {\n          return Promise.resolve({\n            done: true\n          });\n        }\n\n        return requestMethod({\n          method,\n          url,\n          headers\n        }).then(normalizePaginatedListResponse).then(response => {\n          // `response.headers.link` format:\n          // '<https://api.github.com/users/aseemk/followers?page=2>; rel=\"next\", <https://api.github.com/users/aseemk/followers?page=2>; rel=\"last\"'\n          // sets `url` to undefined if \"next\" URL is not present or `link` header is not set\n          url = ((response.headers.link || \"\").match(/<([^>]+)>;\\s*rel=\"next\"/) || [])[1];\n          return {\n            value: response\n          };\n        });\n      }\n\n    })\n  };\n}\n\nfunction paginate(octokit, route, parameters, mapFn) {\n  if (typeof parameters === \"function\") {\n    mapFn = parameters;\n    parameters = undefined;\n  }\n\n  return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);\n}\n\nfunction gather(octokit, results, iterator, mapFn) {\n  return iterator.next().then(result => {\n    if (result.done) {\n      return results;\n    }\n\n    let earlyExit = false;\n\n    function done() {\n      earlyExit = true;\n    }\n\n    results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data);\n\n    if (earlyExit) {\n      return results;\n    }\n\n    return gather(octokit, results, iterator, mapFn);\n  });\n}\n\n/**\n * @param octokit Octokit instance\n * @param options Options passed to Octokit constructor\n */\n\nfunction paginateRest(octokit) {\n  return {\n    paginate: Object.assign(paginate.bind(null, octokit), {\n      iterator: iterator.bind(null, octokit)\n    })\n  };\n}\npaginateRest.VERSION = VERSION;\n\nexports.paginateRest = paginateRest;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 44:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nconst Endpoints = {\n  actions: {\n    addSelectedRepoToOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}\"],\n    cancelWorkflowRun: [\"POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel\"],\n    createOrUpdateOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}\"],\n    createOrUpdateRepoSecret: [\"PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    createRegistrationTokenForOrg: [\"POST /orgs/{org}/actions/runners/registration-token\"],\n    createRegistrationTokenForRepo: [\"POST /repos/{owner}/{repo}/actions/runners/registration-token\"],\n    createRemoveTokenForOrg: [\"POST /orgs/{org}/actions/runners/remove-token\"],\n    createRemoveTokenForRepo: [\"POST /repos/{owner}/{repo}/actions/runners/remove-token\"],\n    createWorkflowDispatch: [\"POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches\"],\n    deleteArtifact: [\"DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}\"],\n    deleteOrgSecret: [\"DELETE /orgs/{org}/actions/secrets/{secret_name}\"],\n    deleteRepoSecret: [\"DELETE /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    deleteSelfHostedRunnerFromOrg: [\"DELETE /orgs/{org}/actions/runners/{runner_id}\"],\n    deleteSelfHostedRunnerFromRepo: [\"DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}\"],\n    deleteWorkflowRun: [\"DELETE /repos/{owner}/{repo}/actions/runs/{run_id}\"],\n    deleteWorkflowRunLogs: [\"DELETE /repos/{owner}/{repo}/actions/runs/{run_id}/logs\"],\n    downloadArtifact: [\"GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}\"],\n    downloadJobLogsForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/jobs/{job_id}/logs\"],\n    downloadWorkflowRunLogs: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs\"],\n    getArtifact: [\"GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}\"],\n    getJobForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/jobs/{job_id}\"],\n    getOrgPublicKey: [\"GET /orgs/{org}/actions/secrets/public-key\"],\n    getOrgSecret: [\"GET /orgs/{org}/actions/secrets/{secret_name}\"],\n    getRepoPublicKey: [\"GET /repos/{owner}/{repo}/actions/secrets/public-key\"],\n    getRepoSecret: [\"GET /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    getSelfHostedRunnerForOrg: [\"GET /orgs/{org}/actions/runners/{runner_id}\"],\n    getSelfHostedRunnerForRepo: [\"GET /repos/{owner}/{repo}/actions/runners/{runner_id}\"],\n    getWorkflow: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}\"],\n    getWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}\"],\n    getWorkflowRunUsage: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/timing\"],\n    getWorkflowUsage: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing\"],\n    listArtifactsForRepo: [\"GET /repos/{owner}/{repo}/actions/artifacts\"],\n    listJobsForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs\"],\n    listOrgSecrets: [\"GET /orgs/{org}/actions/secrets\"],\n    listRepoSecrets: [\"GET /repos/{owner}/{repo}/actions/secrets\"],\n    listRepoWorkflows: [\"GET /repos/{owner}/{repo}/actions/workflows\"],\n    listRunnerApplicationsForOrg: [\"GET /orgs/{org}/actions/runners/downloads\"],\n    listRunnerApplicationsForRepo: [\"GET /repos/{owner}/{repo}/actions/runners/downloads\"],\n    listSelectedReposForOrgSecret: [\"GET /orgs/{org}/actions/secrets/{secret_name}/repositories\"],\n    listSelfHostedRunnersForOrg: [\"GET /orgs/{org}/actions/runners\"],\n    listSelfHostedRunnersForRepo: [\"GET /repos/{owner}/{repo}/actions/runners\"],\n    listWorkflowRunArtifacts: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts\"],\n    listWorkflowRuns: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs\"],\n    listWorkflowRunsForRepo: [\"GET /repos/{owner}/{repo}/actions/runs\"],\n    reRunWorkflow: [\"POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun\"],\n    removeSelectedRepoFromOrgSecret: [\"DELETE /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}\"],\n    setSelectedReposForOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}/repositories\"]\n  },\n  activity: {\n    checkRepoIsStarredByAuthenticatedUser: [\"GET /user/starred/{owner}/{repo}\"],\n    deleteRepoSubscription: [\"DELETE /repos/{owner}/{repo}/subscription\"],\n    deleteThreadSubscription: [\"DELETE /notifications/threads/{thread_id}/subscription\"],\n    getFeeds: [\"GET /feeds\"],\n    getRepoSubscription: [\"GET /repos/{owner}/{repo}/subscription\"],\n    getThread: [\"GET /notifications/threads/{thread_id}\"],\n    getThreadSubscriptionForAuthenticatedUser: [\"GET /notifications/threads/{thread_id}/subscription\"],\n    listEventsForAuthenticatedUser: [\"GET /users/{username}/events\"],\n    listNotificationsForAuthenticatedUser: [\"GET /notifications\"],\n    listOrgEventsForAuthenticatedUser: [\"GET /users/{username}/events/orgs/{org}\"],\n    listPublicEvents: [\"GET /events\"],\n    listPublicEventsForRepoNetwork: [\"GET /networks/{owner}/{repo}/events\"],\n    listPublicEventsForUser: [\"GET /users/{username}/events/public\"],\n    listPublicOrgEvents: [\"GET /orgs/{org}/events\"],\n    listReceivedEventsForUser: [\"GET /users/{username}/received_events\"],\n    listReceivedPublicEventsForUser: [\"GET /users/{username}/received_events/public\"],\n    listRepoEvents: [\"GET /repos/{owner}/{repo}/events\"],\n    listRepoNotificationsForAuthenticatedUser: [\"GET /repos/{owner}/{repo}/notifications\"],\n    listReposStarredByAuthenticatedUser: [\"GET /user/starred\"],\n    listReposStarredByUser: [\"GET /users/{username}/starred\"],\n    listReposWatchedByUser: [\"GET /users/{username}/subscriptions\"],\n    listStargazersForRepo: [\"GET /repos/{owner}/{repo}/stargazers\"],\n    listWatchedReposForAuthenticatedUser: [\"GET /user/subscriptions\"],\n    listWatchersForRepo: [\"GET /repos/{owner}/{repo}/subscribers\"],\n    markNotificationsAsRead: [\"PUT /notifications\"],\n    markRepoNotificationsAsRead: [\"PUT /repos/{owner}/{repo}/notifications\"],\n    markThreadAsRead: [\"PATCH /notifications/threads/{thread_id}\"],\n    setRepoSubscription: [\"PUT /repos/{owner}/{repo}/subscription\"],\n    setThreadSubscription: [\"PUT /notifications/threads/{thread_id}/subscription\"],\n    starRepoForAuthenticatedUser: [\"PUT /user/starred/{owner}/{repo}\"],\n    unstarRepoForAuthenticatedUser: [\"DELETE /user/starred/{owner}/{repo}\"]\n  },\n  apps: {\n    addRepoToInstallation: [\"PUT /user/installations/{installation_id}/repositories/{repository_id}\"],\n    checkToken: [\"POST /applications/{client_id}/token\"],\n    createContentAttachment: [\"POST /content_references/{content_reference_id}/attachments\", {\n      mediaType: {\n        previews: [\"corsair\"]\n      }\n    }],\n    createFromManifest: [\"POST /app-manifests/{code}/conversions\"],\n    createInstallationAccessToken: [\"POST /app/installations/{installation_id}/access_tokens\"],\n    deleteAuthorization: [\"DELETE /applications/{client_id}/grant\"],\n    deleteInstallation: [\"DELETE /app/installations/{installation_id}\"],\n    deleteToken: [\"DELETE /applications/{client_id}/token\"],\n    getAuthenticated: [\"GET /app\"],\n    getBySlug: [\"GET /apps/{app_slug}\"],\n    getInstallation: [\"GET /app/installations/{installation_id}\"],\n    getOrgInstallation: [\"GET /orgs/{org}/installation\"],\n    getRepoInstallation: [\"GET /repos/{owner}/{repo}/installation\"],\n    getSubscriptionPlanForAccount: [\"GET /marketplace_listing/accounts/{account_id}\"],\n    getSubscriptionPlanForAccountStubbed: [\"GET /marketplace_listing/stubbed/accounts/{account_id}\"],\n    getUserInstallation: [\"GET /users/{username}/installation\"],\n    listAccountsForPlan: [\"GET /marketplace_listing/plans/{plan_id}/accounts\"],\n    listAccountsForPlanStubbed: [\"GET /marketplace_listing/stubbed/plans/{plan_id}/accounts\"],\n    listInstallationReposForAuthenticatedUser: [\"GET /user/installations/{installation_id}/repositories\"],\n    listInstallations: [\"GET /app/installations\"],\n    listInstallationsForAuthenticatedUser: [\"GET /user/installations\"],\n    listPlans: [\"GET /marketplace_listing/plans\"],\n    listPlansStubbed: [\"GET /marketplace_listing/stubbed/plans\"],\n    listReposAccessibleToInstallation: [\"GET /installation/repositories\"],\n    listSubscriptionsForAuthenticatedUser: [\"GET /user/marketplace_purchases\"],\n    listSubscriptionsForAuthenticatedUserStubbed: [\"GET /user/marketplace_purchases/stubbed\"],\n    removeRepoFromInstallation: [\"DELETE /user/installations/{installation_id}/repositories/{repository_id}\"],\n    resetToken: [\"PATCH /applications/{client_id}/token\"],\n    revokeInstallationAccessToken: [\"DELETE /installation/token\"],\n    suspendInstallation: [\"PUT /app/installations/{installation_id}/suspended\"],\n    unsuspendInstallation: [\"DELETE /app/installations/{installation_id}/suspended\"]\n  },\n  billing: {\n    getGithubActionsBillingOrg: [\"GET /orgs/{org}/settings/billing/actions\"],\n    getGithubActionsBillingUser: [\"GET /users/{username}/settings/billing/actions\"],\n    getGithubPackagesBillingOrg: [\"GET /orgs/{org}/settings/billing/packages\"],\n    getGithubPackagesBillingUser: [\"GET /users/{username}/settings/billing/packages\"],\n    getSharedStorageBillingOrg: [\"GET /orgs/{org}/settings/billing/shared-storage\"],\n    getSharedStorageBillingUser: [\"GET /users/{username}/settings/billing/shared-storage\"]\n  },\n  checks: {\n    create: [\"POST /repos/{owner}/{repo}/check-runs\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    createSuite: [\"POST /repos/{owner}/{repo}/check-suites\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    get: [\"GET /repos/{owner}/{repo}/check-runs/{check_run_id}\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    getSuite: [\"GET /repos/{owner}/{repo}/check-suites/{check_suite_id}\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    listAnnotations: [\"GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    listForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/check-runs\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    listForSuite: [\"GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    listSuitesForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/check-suites\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    rerequestSuite: [\"POST /repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    setSuitesPreferences: [\"PATCH /repos/{owner}/{repo}/check-suites/preferences\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }],\n    update: [\"PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}\", {\n      mediaType: {\n        previews: [\"antiope\"]\n      }\n    }]\n  },\n  codeScanning: {\n    getAlert: [\"GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}\", {}, {\n      renamedParameters: {\n        alert_id: \"alert_number\"\n      }\n    }],\n    listAlertsForRepo: [\"GET /repos/{owner}/{repo}/code-scanning/alerts\"],\n    listRecentAnalyses: [\"GET /repos/{owner}/{repo}/code-scanning/analyses\"],\n    updateAlert: [\"PATCH /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}\"],\n    uploadSarif: [\"POST /repos/{owner}/{repo}/code-scanning/sarifs\"]\n  },\n  codesOfConduct: {\n    getAllCodesOfConduct: [\"GET /codes_of_conduct\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }],\n    getConductCode: [\"GET /codes_of_conduct/{key}\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }],\n    getForRepo: [\"GET /repos/{owner}/{repo}/community/code_of_conduct\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }]\n  },\n  emojis: {\n    get: [\"GET /emojis\"]\n  },\n  gists: {\n    checkIsStarred: [\"GET /gists/{gist_id}/star\"],\n    create: [\"POST /gists\"],\n    createComment: [\"POST /gists/{gist_id}/comments\"],\n    delete: [\"DELETE /gists/{gist_id}\"],\n    deleteComment: [\"DELETE /gists/{gist_id}/comments/{comment_id}\"],\n    fork: [\"POST /gists/{gist_id}/forks\"],\n    get: [\"GET /gists/{gist_id}\"],\n    getComment: [\"GET /gists/{gist_id}/comments/{comment_id}\"],\n    getRevision: [\"GET /gists/{gist_id}/{sha}\"],\n    list: [\"GET /gists\"],\n    listComments: [\"GET /gists/{gist_id}/comments\"],\n    listCommits: [\"GET /gists/{gist_id}/commits\"],\n    listForUser: [\"GET /users/{username}/gists\"],\n    listForks: [\"GET /gists/{gist_id}/forks\"],\n    listPublic: [\"GET /gists/public\"],\n    listStarred: [\"GET /gists/starred\"],\n    star: [\"PUT /gists/{gist_id}/star\"],\n    unstar: [\"DELETE /gists/{gist_id}/star\"],\n    update: [\"PATCH /gists/{gist_id}\"],\n    updateComment: [\"PATCH /gists/{gist_id}/comments/{comment_id}\"]\n  },\n  git: {\n    createBlob: [\"POST /repos/{owner}/{repo}/git/blobs\"],\n    createCommit: [\"POST /repos/{owner}/{repo}/git/commits\"],\n    createRef: [\"POST /repos/{owner}/{repo}/git/refs\"],\n    createTag: [\"POST /repos/{owner}/{repo}/git/tags\"],\n    createTree: [\"POST /repos/{owner}/{repo}/git/trees\"],\n    deleteRef: [\"DELETE /repos/{owner}/{repo}/git/refs/{ref}\"],\n    getBlob: [\"GET /repos/{owner}/{repo}/git/blobs/{file_sha}\"],\n    getCommit: [\"GET /repos/{owner}/{repo}/git/commits/{commit_sha}\"],\n    getRef: [\"GET /repos/{owner}/{repo}/git/ref/{ref}\"],\n    getTag: [\"GET /repos/{owner}/{repo}/git/tags/{tag_sha}\"],\n    getTree: [\"GET /repos/{owner}/{repo}/git/trees/{tree_sha}\"],\n    listMatchingRefs: [\"GET /repos/{owner}/{repo}/git/matching-refs/{ref}\"],\n    updateRef: [\"PATCH /repos/{owner}/{repo}/git/refs/{ref}\"]\n  },\n  gitignore: {\n    getAllTemplates: [\"GET /gitignore/templates\"],\n    getTemplate: [\"GET /gitignore/templates/{name}\"]\n  },\n  interactions: {\n    getRestrictionsForOrg: [\"GET /orgs/{org}/interaction-limits\", {\n      mediaType: {\n        previews: [\"sombra\"]\n      }\n    }],\n    getRestrictionsForRepo: [\"GET /repos/{owner}/{repo}/interaction-limits\", {\n      mediaType: {\n        previews: [\"sombra\"]\n      }\n    }],\n    removeRestrictionsForOrg: [\"DELETE /orgs/{org}/interaction-limits\", {\n      mediaType: {\n        previews: [\"sombra\"]\n      }\n    }],\n    removeRestrictionsForRepo: [\"DELETE /repos/{owner}/{repo}/interaction-limits\", {\n      mediaType: {\n        previews: [\"sombra\"]\n      }\n    }],\n    setRestrictionsForOrg: [\"PUT /orgs/{org}/interaction-limits\", {\n      mediaType: {\n        previews: [\"sombra\"]\n      }\n    }],\n    setRestrictionsForRepo: [\"PUT /repos/{owner}/{repo}/interaction-limits\", {\n      mediaType: {\n        previews: [\"sombra\"]\n      }\n    }]\n  },\n  issues: {\n    addAssignees: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/assignees\"],\n    addLabels: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    checkUserCanBeAssigned: [\"GET /repos/{owner}/{repo}/assignees/{assignee}\"],\n    create: [\"POST /repos/{owner}/{repo}/issues\"],\n    createComment: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/comments\"],\n    createLabel: [\"POST /repos/{owner}/{repo}/labels\"],\n    createMilestone: [\"POST /repos/{owner}/{repo}/milestones\"],\n    deleteComment: [\"DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    deleteLabel: [\"DELETE /repos/{owner}/{repo}/labels/{name}\"],\n    deleteMilestone: [\"DELETE /repos/{owner}/{repo}/milestones/{milestone_number}\"],\n    get: [\"GET /repos/{owner}/{repo}/issues/{issue_number}\"],\n    getComment: [\"GET /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    getEvent: [\"GET /repos/{owner}/{repo}/issues/events/{event_id}\"],\n    getLabel: [\"GET /repos/{owner}/{repo}/labels/{name}\"],\n    getMilestone: [\"GET /repos/{owner}/{repo}/milestones/{milestone_number}\"],\n    list: [\"GET /issues\"],\n    listAssignees: [\"GET /repos/{owner}/{repo}/assignees\"],\n    listComments: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/comments\"],\n    listCommentsForRepo: [\"GET /repos/{owner}/{repo}/issues/comments\"],\n    listEvents: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/events\"],\n    listEventsForRepo: [\"GET /repos/{owner}/{repo}/issues/events\"],\n    listEventsForTimeline: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/timeline\", {\n      mediaType: {\n        previews: [\"mockingbird\"]\n      }\n    }],\n    listForAuthenticatedUser: [\"GET /user/issues\"],\n    listForOrg: [\"GET /orgs/{org}/issues\"],\n    listForRepo: [\"GET /repos/{owner}/{repo}/issues\"],\n    listLabelsForMilestone: [\"GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels\"],\n    listLabelsForRepo: [\"GET /repos/{owner}/{repo}/labels\"],\n    listLabelsOnIssue: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    listMilestones: [\"GET /repos/{owner}/{repo}/milestones\"],\n    lock: [\"PUT /repos/{owner}/{repo}/issues/{issue_number}/lock\"],\n    removeAllLabels: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    removeAssignees: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/assignees\"],\n    removeLabel: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}\"],\n    setLabels: [\"PUT /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    unlock: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/lock\"],\n    update: [\"PATCH /repos/{owner}/{repo}/issues/{issue_number}\"],\n    updateComment: [\"PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    updateLabel: [\"PATCH /repos/{owner}/{repo}/labels/{name}\"],\n    updateMilestone: [\"PATCH /repos/{owner}/{repo}/milestones/{milestone_number}\"]\n  },\n  licenses: {\n    get: [\"GET /licenses/{license}\"],\n    getAllCommonlyUsed: [\"GET /licenses\"],\n    getForRepo: [\"GET /repos/{owner}/{repo}/license\"]\n  },\n  markdown: {\n    render: [\"POST /markdown\"],\n    renderRaw: [\"POST /markdown/raw\", {\n      headers: {\n        \"content-type\": \"text/plain; charset=utf-8\"\n      }\n    }]\n  },\n  meta: {\n    get: [\"GET /meta\"]\n  },\n  migrations: {\n    cancelImport: [\"DELETE /repos/{owner}/{repo}/import\"],\n    deleteArchiveForAuthenticatedUser: [\"DELETE /user/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    deleteArchiveForOrg: [\"DELETE /orgs/{org}/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    downloadArchiveForOrg: [\"GET /orgs/{org}/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getArchiveForAuthenticatedUser: [\"GET /user/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getCommitAuthors: [\"GET /repos/{owner}/{repo}/import/authors\"],\n    getImportStatus: [\"GET /repos/{owner}/{repo}/import\"],\n    getLargeFiles: [\"GET /repos/{owner}/{repo}/import/large_files\"],\n    getStatusForAuthenticatedUser: [\"GET /user/migrations/{migration_id}\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getStatusForOrg: [\"GET /orgs/{org}/migrations/{migration_id}\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listForAuthenticatedUser: [\"GET /user/migrations\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listForOrg: [\"GET /orgs/{org}/migrations\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listReposForOrg: [\"GET /orgs/{org}/migrations/{migration_id}/repositories\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listReposForUser: [\"GET /user/migrations/{migration_id}/repositories\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    mapCommitAuthor: [\"PATCH /repos/{owner}/{repo}/import/authors/{author_id}\"],\n    setLfsPreference: [\"PATCH /repos/{owner}/{repo}/import/lfs\"],\n    startForAuthenticatedUser: [\"POST /user/migrations\"],\n    startForOrg: [\"POST /orgs/{org}/migrations\"],\n    startImport: [\"PUT /repos/{owner}/{repo}/import\"],\n    unlockRepoForAuthenticatedUser: [\"DELETE /user/migrations/{migration_id}/repos/{repo_name}/lock\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    unlockRepoForOrg: [\"DELETE /orgs/{org}/migrations/{migration_id}/repos/{repo_name}/lock\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    updateImport: [\"PATCH /repos/{owner}/{repo}/import\"]\n  },\n  orgs: {\n    blockUser: [\"PUT /orgs/{org}/blocks/{username}\"],\n    checkBlockedUser: [\"GET /orgs/{org}/blocks/{username}\"],\n    checkMembershipForUser: [\"GET /orgs/{org}/members/{username}\"],\n    checkPublicMembershipForUser: [\"GET /orgs/{org}/public_members/{username}\"],\n    convertMemberToOutsideCollaborator: [\"PUT /orgs/{org}/outside_collaborators/{username}\"],\n    createInvitation: [\"POST /orgs/{org}/invitations\"],\n    createWebhook: [\"POST /orgs/{org}/hooks\"],\n    deleteWebhook: [\"DELETE /orgs/{org}/hooks/{hook_id}\"],\n    get: [\"GET /orgs/{org}\"],\n    getMembershipForAuthenticatedUser: [\"GET /user/memberships/orgs/{org}\"],\n    getMembershipForUser: [\"GET /orgs/{org}/memberships/{username}\"],\n    getWebhook: [\"GET /orgs/{org}/hooks/{hook_id}\"],\n    list: [\"GET /organizations\"],\n    listAppInstallations: [\"GET /orgs/{org}/installations\"],\n    listBlockedUsers: [\"GET /orgs/{org}/blocks\"],\n    listForAuthenticatedUser: [\"GET /user/orgs\"],\n    listForUser: [\"GET /users/{username}/orgs\"],\n    listInvitationTeams: [\"GET /orgs/{org}/invitations/{invitation_id}/teams\"],\n    listMembers: [\"GET /orgs/{org}/members\"],\n    listMembershipsForAuthenticatedUser: [\"GET /user/memberships/orgs\"],\n    listOutsideCollaborators: [\"GET /orgs/{org}/outside_collaborators\"],\n    listPendingInvitations: [\"GET /orgs/{org}/invitations\"],\n    listPublicMembers: [\"GET /orgs/{org}/public_members\"],\n    listWebhooks: [\"GET /orgs/{org}/hooks\"],\n    pingWebhook: [\"POST /orgs/{org}/hooks/{hook_id}/pings\"],\n    removeMember: [\"DELETE /orgs/{org}/members/{username}\"],\n    removeMembershipForUser: [\"DELETE /orgs/{org}/memberships/{username}\"],\n    removeOutsideCollaborator: [\"DELETE /orgs/{org}/outside_collaborators/{username}\"],\n    removePublicMembershipForAuthenticatedUser: [\"DELETE /orgs/{org}/public_members/{username}\"],\n    setMembershipForUser: [\"PUT /orgs/{org}/memberships/{username}\"],\n    setPublicMembershipForAuthenticatedUser: [\"PUT /orgs/{org}/public_members/{username}\"],\n    unblockUser: [\"DELETE /orgs/{org}/blocks/{username}\"],\n    update: [\"PATCH /orgs/{org}\"],\n    updateMembershipForAuthenticatedUser: [\"PATCH /user/memberships/orgs/{org}\"],\n    updateWebhook: [\"PATCH /orgs/{org}/hooks/{hook_id}\"]\n  },\n  projects: {\n    addCollaborator: [\"PUT /projects/{project_id}/collaborators/{username}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createCard: [\"POST /projects/columns/{column_id}/cards\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createColumn: [\"POST /projects/{project_id}/columns\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForAuthenticatedUser: [\"POST /user/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForOrg: [\"POST /orgs/{org}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForRepo: [\"POST /repos/{owner}/{repo}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    delete: [\"DELETE /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    deleteCard: [\"DELETE /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    deleteColumn: [\"DELETE /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    get: [\"GET /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getCard: [\"GET /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getColumn: [\"GET /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getPermissionForUser: [\"GET /projects/{project_id}/collaborators/{username}/permission\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listCards: [\"GET /projects/columns/{column_id}/cards\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listCollaborators: [\"GET /projects/{project_id}/collaborators\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listColumns: [\"GET /projects/{project_id}/columns\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForOrg: [\"GET /orgs/{org}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForRepo: [\"GET /repos/{owner}/{repo}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForUser: [\"GET /users/{username}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    moveCard: [\"POST /projects/columns/cards/{card_id}/moves\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    moveColumn: [\"POST /projects/columns/{column_id}/moves\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    removeCollaborator: [\"DELETE /projects/{project_id}/collaborators/{username}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    update: [\"PATCH /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    updateCard: [\"PATCH /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    updateColumn: [\"PATCH /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }]\n  },\n  pulls: {\n    checkIfMerged: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/merge\"],\n    create: [\"POST /repos/{owner}/{repo}/pulls\"],\n    createReplyForReviewComment: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies\"],\n    createReview: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews\"],\n    createReviewComment: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/comments\"],\n    deletePendingReview: [\"DELETE /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    deleteReviewComment: [\"DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}\"],\n    dismissReview: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals\"],\n    get: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}\"],\n    getReview: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    getReviewComment: [\"GET /repos/{owner}/{repo}/pulls/comments/{comment_id}\"],\n    list: [\"GET /repos/{owner}/{repo}/pulls\"],\n    listCommentsForReview: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments\"],\n    listCommits: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/commits\"],\n    listFiles: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\"],\n    listRequestedReviewers: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    listReviewComments: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/comments\"],\n    listReviewCommentsForRepo: [\"GET /repos/{owner}/{repo}/pulls/comments\"],\n    listReviews: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews\"],\n    merge: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge\"],\n    removeRequestedReviewers: [\"DELETE /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    requestReviewers: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    submitReview: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/events\"],\n    update: [\"PATCH /repos/{owner}/{repo}/pulls/{pull_number}\"],\n    updateBranch: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch\", {\n      mediaType: {\n        previews: [\"lydian\"]\n      }\n    }],\n    updateReview: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    updateReviewComment: [\"PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}\"]\n  },\n  rateLimit: {\n    get: [\"GET /rate_limit\"]\n  },\n  reactions: {\n    createForCommitComment: [\"POST /repos/{owner}/{repo}/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForIssue: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForIssueComment: [\"POST /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForPullRequestReviewComment: [\"POST /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForTeamDiscussionCommentInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForTeamDiscussionInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForCommitComment: [\"DELETE /repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForIssue: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForIssueComment: [\"DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForPullRequestComment: [\"DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForTeamDiscussion: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForTeamDiscussionComment: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteLegacy: [\"DELETE /reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }, {\n      deprecated: \"octokit.reactions.deleteLegacy() is deprecated, see https://developer.github.com/v3/reactions/#delete-a-reaction-legacy\"\n    }],\n    listForCommitComment: [\"GET /repos/{owner}/{repo}/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForIssue: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForIssueComment: [\"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForPullRequestReviewComment: [\"GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForTeamDiscussionCommentInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForTeamDiscussionInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }]\n  },\n  repos: {\n    acceptInvitation: [\"PATCH /user/repository_invitations/{invitation_id}\"],\n    addAppAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    addCollaborator: [\"PUT /repos/{owner}/{repo}/collaborators/{username}\"],\n    addStatusCheckContexts: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    addTeamAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    addUserAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    checkCollaborator: [\"GET /repos/{owner}/{repo}/collaborators/{username}\"],\n    checkVulnerabilityAlerts: [\"GET /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    compareCommits: [\"GET /repos/{owner}/{repo}/compare/{base}...{head}\"],\n    createCommitComment: [\"POST /repos/{owner}/{repo}/commits/{commit_sha}/comments\"],\n    createCommitSignatureProtection: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    createCommitStatus: [\"POST /repos/{owner}/{repo}/statuses/{sha}\"],\n    createDeployKey: [\"POST /repos/{owner}/{repo}/keys\"],\n    createDeployment: [\"POST /repos/{owner}/{repo}/deployments\"],\n    createDeploymentStatus: [\"POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses\"],\n    createDispatchEvent: [\"POST /repos/{owner}/{repo}/dispatches\"],\n    createForAuthenticatedUser: [\"POST /user/repos\"],\n    createFork: [\"POST /repos/{owner}/{repo}/forks\"],\n    createInOrg: [\"POST /orgs/{org}/repos\"],\n    createOrUpdateFileContents: [\"PUT /repos/{owner}/{repo}/contents/{path}\"],\n    createPagesSite: [\"POST /repos/{owner}/{repo}/pages\", {\n      mediaType: {\n        previews: [\"switcheroo\"]\n      }\n    }],\n    createRelease: [\"POST /repos/{owner}/{repo}/releases\"],\n    createUsingTemplate: [\"POST /repos/{template_owner}/{template_repo}/generate\", {\n      mediaType: {\n        previews: [\"baptiste\"]\n      }\n    }],\n    createWebhook: [\"POST /repos/{owner}/{repo}/hooks\"],\n    declineInvitation: [\"DELETE /user/repository_invitations/{invitation_id}\"],\n    delete: [\"DELETE /repos/{owner}/{repo}\"],\n    deleteAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions\"],\n    deleteAdminBranchProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    deleteBranchProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    deleteCommitComment: [\"DELETE /repos/{owner}/{repo}/comments/{comment_id}\"],\n    deleteCommitSignatureProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    deleteDeployKey: [\"DELETE /repos/{owner}/{repo}/keys/{key_id}\"],\n    deleteDeployment: [\"DELETE /repos/{owner}/{repo}/deployments/{deployment_id}\"],\n    deleteFile: [\"DELETE /repos/{owner}/{repo}/contents/{path}\"],\n    deleteInvitation: [\"DELETE /repos/{owner}/{repo}/invitations/{invitation_id}\"],\n    deletePagesSite: [\"DELETE /repos/{owner}/{repo}/pages\", {\n      mediaType: {\n        previews: [\"switcheroo\"]\n      }\n    }],\n    deletePullRequestReviewProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    deleteRelease: [\"DELETE /repos/{owner}/{repo}/releases/{release_id}\"],\n    deleteReleaseAsset: [\"DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    deleteWebhook: [\"DELETE /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    disableAutomatedSecurityFixes: [\"DELETE /repos/{owner}/{repo}/automated-security-fixes\", {\n      mediaType: {\n        previews: [\"london\"]\n      }\n    }],\n    disableVulnerabilityAlerts: [\"DELETE /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    downloadArchive: [\"GET /repos/{owner}/{repo}/{archive_format}/{ref}\"],\n    enableAutomatedSecurityFixes: [\"PUT /repos/{owner}/{repo}/automated-security-fixes\", {\n      mediaType: {\n        previews: [\"london\"]\n      }\n    }],\n    enableVulnerabilityAlerts: [\"PUT /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    get: [\"GET /repos/{owner}/{repo}\"],\n    getAccessRestrictions: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions\"],\n    getAdminBranchProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    getAllStatusCheckContexts: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\"],\n    getAllTopics: [\"GET /repos/{owner}/{repo}/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    getAppsWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\"],\n    getBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}\"],\n    getBranchProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    getClones: [\"GET /repos/{owner}/{repo}/traffic/clones\"],\n    getCodeFrequencyStats: [\"GET /repos/{owner}/{repo}/stats/code_frequency\"],\n    getCollaboratorPermissionLevel: [\"GET /repos/{owner}/{repo}/collaborators/{username}/permission\"],\n    getCombinedStatusForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/status\"],\n    getCommit: [\"GET /repos/{owner}/{repo}/commits/{ref}\"],\n    getCommitActivityStats: [\"GET /repos/{owner}/{repo}/stats/commit_activity\"],\n    getCommitComment: [\"GET /repos/{owner}/{repo}/comments/{comment_id}\"],\n    getCommitSignatureProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    getCommunityProfileMetrics: [\"GET /repos/{owner}/{repo}/community/profile\", {\n      mediaType: {\n        previews: [\"black-panther\"]\n      }\n    }],\n    getContent: [\"GET /repos/{owner}/{repo}/contents/{path}\"],\n    getContributorsStats: [\"GET /repos/{owner}/{repo}/stats/contributors\"],\n    getDeployKey: [\"GET /repos/{owner}/{repo}/keys/{key_id}\"],\n    getDeployment: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}\"],\n    getDeploymentStatus: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}\"],\n    getLatestPagesBuild: [\"GET /repos/{owner}/{repo}/pages/builds/latest\"],\n    getLatestRelease: [\"GET /repos/{owner}/{repo}/releases/latest\"],\n    getPages: [\"GET /repos/{owner}/{repo}/pages\"],\n    getPagesBuild: [\"GET /repos/{owner}/{repo}/pages/builds/{build_id}\"],\n    getParticipationStats: [\"GET /repos/{owner}/{repo}/stats/participation\"],\n    getPullRequestReviewProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    getPunchCardStats: [\"GET /repos/{owner}/{repo}/stats/punch_card\"],\n    getReadme: [\"GET /repos/{owner}/{repo}/readme\"],\n    getRelease: [\"GET /repos/{owner}/{repo}/releases/{release_id}\"],\n    getReleaseAsset: [\"GET /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    getReleaseByTag: [\"GET /repos/{owner}/{repo}/releases/tags/{tag}\"],\n    getStatusChecksProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    getTeamsWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\"],\n    getTopPaths: [\"GET /repos/{owner}/{repo}/traffic/popular/paths\"],\n    getTopReferrers: [\"GET /repos/{owner}/{repo}/traffic/popular/referrers\"],\n    getUsersWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\"],\n    getViews: [\"GET /repos/{owner}/{repo}/traffic/views\"],\n    getWebhook: [\"GET /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    listBranches: [\"GET /repos/{owner}/{repo}/branches\"],\n    listBranchesForHeadCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head\", {\n      mediaType: {\n        previews: [\"groot\"]\n      }\n    }],\n    listCollaborators: [\"GET /repos/{owner}/{repo}/collaborators\"],\n    listCommentsForCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/comments\"],\n    listCommitCommentsForRepo: [\"GET /repos/{owner}/{repo}/comments\"],\n    listCommitStatusesForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/statuses\"],\n    listCommits: [\"GET /repos/{owner}/{repo}/commits\"],\n    listContributors: [\"GET /repos/{owner}/{repo}/contributors\"],\n    listDeployKeys: [\"GET /repos/{owner}/{repo}/keys\"],\n    listDeploymentStatuses: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses\"],\n    listDeployments: [\"GET /repos/{owner}/{repo}/deployments\"],\n    listForAuthenticatedUser: [\"GET /user/repos\"],\n    listForOrg: [\"GET /orgs/{org}/repos\"],\n    listForUser: [\"GET /users/{username}/repos\"],\n    listForks: [\"GET /repos/{owner}/{repo}/forks\"],\n    listInvitations: [\"GET /repos/{owner}/{repo}/invitations\"],\n    listInvitationsForAuthenticatedUser: [\"GET /user/repository_invitations\"],\n    listLanguages: [\"GET /repos/{owner}/{repo}/languages\"],\n    listPagesBuilds: [\"GET /repos/{owner}/{repo}/pages/builds\"],\n    listPublic: [\"GET /repositories\"],\n    listPullRequestsAssociatedWithCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls\", {\n      mediaType: {\n        previews: [\"groot\"]\n      }\n    }],\n    listReleaseAssets: [\"GET /repos/{owner}/{repo}/releases/{release_id}/assets\"],\n    listReleases: [\"GET /repos/{owner}/{repo}/releases\"],\n    listTags: [\"GET /repos/{owner}/{repo}/tags\"],\n    listTeams: [\"GET /repos/{owner}/{repo}/teams\"],\n    listWebhooks: [\"GET /repos/{owner}/{repo}/hooks\"],\n    merge: [\"POST /repos/{owner}/{repo}/merges\"],\n    pingWebhook: [\"POST /repos/{owner}/{repo}/hooks/{hook_id}/pings\"],\n    removeAppAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    removeCollaborator: [\"DELETE /repos/{owner}/{repo}/collaborators/{username}\"],\n    removeStatusCheckContexts: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    removeStatusCheckProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    removeTeamAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    removeUserAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    replaceAllTopics: [\"PUT /repos/{owner}/{repo}/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    requestPagesBuild: [\"POST /repos/{owner}/{repo}/pages/builds\"],\n    setAdminBranchProtection: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    setAppAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    setStatusCheckContexts: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    setTeamAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    setUserAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    testPushWebhook: [\"POST /repos/{owner}/{repo}/hooks/{hook_id}/tests\"],\n    transfer: [\"POST /repos/{owner}/{repo}/transfer\"],\n    update: [\"PATCH /repos/{owner}/{repo}\"],\n    updateBranchProtection: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    updateCommitComment: [\"PATCH /repos/{owner}/{repo}/comments/{comment_id}\"],\n    updateInformationAboutPagesSite: [\"PUT /repos/{owner}/{repo}/pages\"],\n    updateInvitation: [\"PATCH /repos/{owner}/{repo}/invitations/{invitation_id}\"],\n    updatePullRequestReviewProtection: [\"PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    updateRelease: [\"PATCH /repos/{owner}/{repo}/releases/{release_id}\"],\n    updateReleaseAsset: [\"PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    updateStatusCheckPotection: [\"PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    updateWebhook: [\"PATCH /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    uploadReleaseAsset: [\"POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}\", {\n      baseUrl: \"https://uploads.github.com\"\n    }]\n  },\n  search: {\n    code: [\"GET /search/code\"],\n    commits: [\"GET /search/commits\", {\n      mediaType: {\n        previews: [\"cloak\"]\n      }\n    }],\n    issuesAndPullRequests: [\"GET /search/issues\"],\n    labels: [\"GET /search/labels\"],\n    repos: [\"GET /search/repositories\"],\n    topics: [\"GET /search/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    users: [\"GET /search/users\"]\n  },\n  teams: {\n    addOrUpdateMembershipForUserInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    addOrUpdateProjectPermissionsInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    addOrUpdateRepoPermissionsInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    checkPermissionsForProjectInOrg: [\"GET /orgs/{org}/teams/{team_slug}/projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    checkPermissionsForRepoInOrg: [\"GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    create: [\"POST /orgs/{org}/teams\"],\n    createDiscussionCommentInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments\"],\n    createDiscussionInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions\"],\n    deleteDiscussionCommentInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    deleteDiscussionInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    deleteInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}\"],\n    getByName: [\"GET /orgs/{org}/teams/{team_slug}\"],\n    getDiscussionCommentInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    getDiscussionInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    getMembershipForUserInOrg: [\"GET /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    list: [\"GET /orgs/{org}/teams\"],\n    listChildInOrg: [\"GET /orgs/{org}/teams/{team_slug}/teams\"],\n    listDiscussionCommentsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments\"],\n    listDiscussionsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions\"],\n    listForAuthenticatedUser: [\"GET /user/teams\"],\n    listMembersInOrg: [\"GET /orgs/{org}/teams/{team_slug}/members\"],\n    listPendingInvitationsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/invitations\"],\n    listProjectsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listReposInOrg: [\"GET /orgs/{org}/teams/{team_slug}/repos\"],\n    removeMembershipForUserInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    removeProjectInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}\"],\n    removeRepoInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    updateDiscussionCommentInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    updateDiscussionInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    updateInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}\"]\n  },\n  users: {\n    addEmailForAuthenticated: [\"POST /user/emails\"],\n    block: [\"PUT /user/blocks/{username}\"],\n    checkBlocked: [\"GET /user/blocks/{username}\"],\n    checkFollowingForUser: [\"GET /users/{username}/following/{target_user}\"],\n    checkPersonIsFollowedByAuthenticated: [\"GET /user/following/{username}\"],\n    createGpgKeyForAuthenticated: [\"POST /user/gpg_keys\"],\n    createPublicSshKeyForAuthenticated: [\"POST /user/keys\"],\n    deleteEmailForAuthenticated: [\"DELETE /user/emails\"],\n    deleteGpgKeyForAuthenticated: [\"DELETE /user/gpg_keys/{gpg_key_id}\"],\n    deletePublicSshKeyForAuthenticated: [\"DELETE /user/keys/{key_id}\"],\n    follow: [\"PUT /user/following/{username}\"],\n    getAuthenticated: [\"GET /user\"],\n    getByUsername: [\"GET /users/{username}\"],\n    getContextForUser: [\"GET /users/{username}/hovercard\"],\n    getGpgKeyForAuthenticated: [\"GET /user/gpg_keys/{gpg_key_id}\"],\n    getPublicSshKeyForAuthenticated: [\"GET /user/keys/{key_id}\"],\n    list: [\"GET /users\"],\n    listBlockedByAuthenticated: [\"GET /user/blocks\"],\n    listEmailsForAuthenticated: [\"GET /user/emails\"],\n    listFollowedByAuthenticated: [\"GET /user/following\"],\n    listFollowersForAuthenticatedUser: [\"GET /user/followers\"],\n    listFollowersForUser: [\"GET /users/{username}/followers\"],\n    listFollowingForUser: [\"GET /users/{username}/following\"],\n    listGpgKeysForAuthenticated: [\"GET /user/gpg_keys\"],\n    listGpgKeysForUser: [\"GET /users/{username}/gpg_keys\"],\n    listPublicEmailsForAuthenticated: [\"GET /user/public_emails\"],\n    listPublicKeysForUser: [\"GET /users/{username}/keys\"],\n    listPublicSshKeysForAuthenticated: [\"GET /user/keys\"],\n    setPrimaryEmailVisibilityForAuthenticated: [\"PATCH /user/email/visibility\"],\n    unblock: [\"DELETE /user/blocks/{username}\"],\n    unfollow: [\"DELETE /user/following/{username}\"],\n    updateAuthenticated: [\"PATCH /user\"]\n  }\n};\n\nconst VERSION = \"4.2.0\";\n\nfunction endpointsToMethods(octokit, endpointsMap) {\n  const newMethods = {};\n\n  for (const [scope, endpoints] of Object.entries(endpointsMap)) {\n    for (const [methodName, endpoint] of Object.entries(endpoints)) {\n      const [route, defaults, decorations] = endpoint;\n      const [method, url] = route.split(/ /);\n      const endpointDefaults = Object.assign({\n        method,\n        url\n      }, defaults);\n\n      if (!newMethods[scope]) {\n        newMethods[scope] = {};\n      }\n\n      const scopeMethods = newMethods[scope];\n\n      if (decorations) {\n        scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations);\n        continue;\n      }\n\n      scopeMethods[methodName] = octokit.request.defaults(endpointDefaults);\n    }\n  }\n\n  return newMethods;\n}\n\nfunction decorate(octokit, scope, methodName, defaults, decorations) {\n  const requestWithDefaults = octokit.request.defaults(defaults);\n  /* istanbul ignore next */\n\n  function withDecorations(...args) {\n    // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n    let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData`\n\n    if (decorations.mapToData) {\n      options = Object.assign({}, options, {\n        data: options[decorations.mapToData],\n        [decorations.mapToData]: undefined\n      });\n      return requestWithDefaults(options);\n    }\n\n    if (decorations.renamed) {\n      const [newScope, newMethodName] = decorations.renamed;\n      octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`);\n    }\n\n    if (decorations.deprecated) {\n      octokit.log.warn(decorations.deprecated);\n    }\n\n    if (decorations.renamedParameters) {\n      // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n      const options = requestWithDefaults.endpoint.merge(...args);\n\n      for (const [name, alias] of Object.entries(decorations.renamedParameters)) {\n        if (name in options) {\n          octokit.log.warn(`\"${name}\" parameter is deprecated for \"octokit.${scope}.${methodName}()\". Use \"${alias}\" instead`);\n\n          if (!(alias in options)) {\n            options[alias] = options[name];\n          }\n\n          delete options[name];\n        }\n      }\n\n      return requestWithDefaults(options);\n    } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n\n\n    return requestWithDefaults(...args);\n  }\n\n  return Object.assign(withDecorations, requestWithDefaults);\n}\n\n/**\n * This plugin is a 1:1 copy of internal @octokit/rest plugins. The primary\n * goal is to rebuild @octokit/rest on top of @octokit/core. Once that is\n * done, we will remove the registerEndpoints methods and return the methods\n * directly as with the other plugins. At that point we will also remove the\n * legacy workarounds and deprecations.\n *\n * See the plan at\n * https://github.com/octokit/plugin-rest-endpoint-methods.js/pull/1\n */\n\nfunction restEndpointMethods(octokit) {\n  return endpointsToMethods(octokit, Endpoints);\n}\nrestEndpointMethods.VERSION = VERSION;\n\nexports.restEndpointMethods = restEndpointMethods;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 537:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar deprecation = __webpack_require__(481);\nvar once = _interopDefault(__webpack_require__(223));\n\nconst logOnce = once(deprecation => console.warn(deprecation));\n/**\n * Error with extra properties to help with debugging\n */\n\nclass RequestError extends Error {\n  constructor(message, statusCode, options) {\n    super(message); // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n\n    this.name = \"HttpError\";\n    this.status = statusCode;\n    Object.defineProperty(this, \"code\", {\n      get() {\n        logOnce(new deprecation.Deprecation(\"[@octokit/request-error] `error.code` is deprecated, use `error.status`.\"));\n        return statusCode;\n      }\n\n    });\n    this.headers = options.headers || {}; // redact request credentials without mutating original request options\n\n    const requestCopy = Object.assign({}, options.request);\n\n    if (options.request.headers.authorization) {\n      requestCopy.headers = Object.assign({}, options.request.headers, {\n        authorization: options.request.headers.authorization.replace(/ .*$/, \" [REDACTED]\")\n      });\n    }\n\n    requestCopy.url = requestCopy.url // client_id & client_secret can be passed as URL query parameters to increase rate limit\n    // see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications\n    .replace(/\\bclient_secret=\\w+/g, \"client_secret=[REDACTED]\") // OAuth tokens can be passed as URL query parameters, although it is not recommended\n    // see https://developer.github.com/v3/#oauth2-token-sent-in-a-header\n    .replace(/\\baccess_token=\\w+/g, \"access_token=[REDACTED]\");\n    this.request = requestCopy;\n  }\n\n}\n\nexports.RequestError = RequestError;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 234:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar endpoint = __webpack_require__(440);\nvar universalUserAgent = __webpack_require__(429);\nvar isPlainObject = __webpack_require__(287);\nvar nodeFetch = _interopDefault(__webpack_require__(467));\nvar requestError = __webpack_require__(537);\n\nconst VERSION = \"5.4.9\";\n\nfunction getBufferResponse(response) {\n  return response.arrayBuffer();\n}\n\nfunction fetchWrapper(requestOptions) {\n  if (isPlainObject.isPlainObject(requestOptions.body) || Array.isArray(requestOptions.body)) {\n    requestOptions.body = JSON.stringify(requestOptions.body);\n  }\n\n  let headers = {};\n  let status;\n  let url;\n  const fetch = requestOptions.request && requestOptions.request.fetch || nodeFetch;\n  return fetch(requestOptions.url, Object.assign({\n    method: requestOptions.method,\n    body: requestOptions.body,\n    headers: requestOptions.headers,\n    redirect: requestOptions.redirect\n  }, requestOptions.request)).then(response => {\n    url = response.url;\n    status = response.status;\n\n    for (const keyAndValue of response.headers) {\n      headers[keyAndValue[0]] = keyAndValue[1];\n    }\n\n    if (status === 204 || status === 205) {\n      return;\n    } // GitHub API returns 200 for HEAD requests\n\n\n    if (requestOptions.method === \"HEAD\") {\n      if (status < 400) {\n        return;\n      }\n\n      throw new requestError.RequestError(response.statusText, status, {\n        headers,\n        request: requestOptions\n      });\n    }\n\n    if (status === 304) {\n      throw new requestError.RequestError(\"Not modified\", status, {\n        headers,\n        request: requestOptions\n      });\n    }\n\n    if (status >= 400) {\n      return response.text().then(message => {\n        const error = new requestError.RequestError(message, status, {\n          headers,\n          request: requestOptions\n        });\n\n        try {\n          let responseBody = JSON.parse(error.message);\n          Object.assign(error, responseBody);\n          let errors = responseBody.errors; // Assumption `errors` would always be in Array format\n\n          error.message = error.message + \": \" + errors.map(JSON.stringify).join(\", \");\n        } catch (e) {// ignore, see octokit/rest.js#684\n        }\n\n        throw error;\n      });\n    }\n\n    const contentType = response.headers.get(\"content-type\");\n\n    if (/application\\/json/.test(contentType)) {\n      return response.json();\n    }\n\n    if (!contentType || /^text\\/|charset=utf-8$/.test(contentType)) {\n      return response.text();\n    }\n\n    return getBufferResponse(response);\n  }).then(data => {\n    return {\n      status,\n      url,\n      headers,\n      data\n    };\n  }).catch(error => {\n    if (error instanceof requestError.RequestError) {\n      throw error;\n    }\n\n    throw new requestError.RequestError(error.message, 500, {\n      headers,\n      request: requestOptions\n    });\n  });\n}\n\nfunction withDefaults(oldEndpoint, newDefaults) {\n  const endpoint = oldEndpoint.defaults(newDefaults);\n\n  const newApi = function (route, parameters) {\n    const endpointOptions = endpoint.merge(route, parameters);\n\n    if (!endpointOptions.request || !endpointOptions.request.hook) {\n      return fetchWrapper(endpoint.parse(endpointOptions));\n    }\n\n    const request = (route, parameters) => {\n      return fetchWrapper(endpoint.parse(endpoint.merge(route, parameters)));\n    };\n\n    Object.assign(request, {\n      endpoint,\n      defaults: withDefaults.bind(null, endpoint)\n    });\n    return endpointOptions.request.hook(request, endpointOptions);\n  };\n\n  return Object.assign(newApi, {\n    endpoint,\n    defaults: withDefaults.bind(null, endpoint)\n  });\n}\n\nconst request = withDefaults(endpoint.endpoint, {\n  headers: {\n    \"user-agent\": `octokit-request.js/${VERSION} ${universalUserAgent.getUserAgent()}`\n  }\n});\n\nexports.request = request;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 682:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nvar register = __webpack_require__(670)\nvar addHook = __webpack_require__(549)\nvar removeHook = __webpack_require__(819)\n\n// bind with array of arguments: https://stackoverflow.com/a/21792913\nvar bind = Function.bind\nvar bindable = bind.bind(bind)\n\nfunction bindApi (hook, state, name) {\n  var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state])\n  hook.api = { remove: removeHookRef }\n  hook.remove = removeHookRef\n\n  ;['before', 'error', 'after', 'wrap'].forEach(function (kind) {\n    var args = name ? [state, kind, name] : [state, kind]\n    hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args)\n  })\n}\n\nfunction HookSingular () {\n  var singularHookName = 'h'\n  var singularHookState = {\n    registry: {}\n  }\n  var singularHook = register.bind(null, singularHookState, singularHookName)\n  bindApi(singularHook, singularHookState, singularHookName)\n  return singularHook\n}\n\nfunction HookCollection () {\n  var state = {\n    registry: {}\n  }\n\n  var hook = register.bind(null, state)\n  bindApi(hook, state)\n\n  return hook\n}\n\nvar collectionHookDeprecationMessageDisplayed = false\nfunction Hook () {\n  if (!collectionHookDeprecationMessageDisplayed) {\n    console.warn('[before-after-hook]: \"Hook()\" repurposing warning, use \"Hook.Collection()\". Read more: https://git.io/upgrade-before-after-hook-to-1.4')\n    collectionHookDeprecationMessageDisplayed = true\n  }\n  return HookCollection()\n}\n\nHook.Singular = HookSingular.bind()\nHook.Collection = HookCollection.bind()\n\nmodule.exports = Hook\n// expose constructors as a named property for TypeScript\nmodule.exports.Hook = Hook\nmodule.exports.Singular = Hook.Singular\nmodule.exports.Collection = Hook.Collection\n\n\n/***/ }),\n\n/***/ 549:\n/***/ ((module) => {\n\nmodule.exports = addHook\n\nfunction addHook (state, kind, name, hook) {\n  var orig = hook\n  if (!state.registry[name]) {\n    state.registry[name] = []\n  }\n\n  if (kind === 'before') {\n    hook = function (method, options) {\n      return Promise.resolve()\n        .then(orig.bind(null, options))\n        .then(method.bind(null, options))\n    }\n  }\n\n  if (kind === 'after') {\n    hook = function (method, options) {\n      var result\n      return Promise.resolve()\n        .then(method.bind(null, options))\n        .then(function (result_) {\n          result = result_\n          return orig(result, options)\n        })\n        .then(function () {\n          return result\n        })\n    }\n  }\n\n  if (kind === 'error') {\n    hook = function (method, options) {\n      return Promise.resolve()\n        .then(method.bind(null, options))\n        .catch(function (error) {\n          return orig(error, options)\n        })\n    }\n  }\n\n  state.registry[name].push({\n    hook: hook,\n    orig: orig\n  })\n}\n\n\n/***/ }),\n\n/***/ 670:\n/***/ ((module) => {\n\nmodule.exports = register\n\nfunction register (state, name, method, options) {\n  if (typeof method !== 'function') {\n    throw new Error('method for before hook must be a function')\n  }\n\n  if (!options) {\n    options = {}\n  }\n\n  if (Array.isArray(name)) {\n    return name.reverse().reduce(function (callback, name) {\n      return register.bind(null, state, name, callback, options)\n    }, method)()\n  }\n\n  return Promise.resolve()\n    .then(function () {\n      if (!state.registry[name]) {\n        return method(options)\n      }\n\n      return (state.registry[name]).reduce(function (method, registered) {\n        return registered.hook.bind(null, method, options)\n      }, method)()\n    })\n}\n\n\n/***/ }),\n\n/***/ 819:\n/***/ ((module) => {\n\nmodule.exports = removeHook\n\nfunction removeHook (state, name, method) {\n  if (!state.registry[name]) {\n    return\n  }\n\n  var index = state.registry[name]\n    .map(function (registered) { return registered.orig })\n    .indexOf(method)\n\n  if (index === -1) {\n    return\n  }\n\n  state.registry[name].splice(index, 1)\n}\n\n\n/***/ }),\n\n/***/ 481:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nclass Deprecation extends Error {\n  constructor(message) {\n    super(message); // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n\n    this.name = 'Deprecation';\n  }\n\n}\n\nexports.Deprecation = Deprecation;\n\n\n/***/ }),\n\n/***/ 287:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\n/*!\n * is-plain-object <https://github.com/jonschlinkert/is-plain-object>\n *\n * Copyright (c) 2014-2017, Jon Schlinkert.\n * Released under the MIT License.\n */\n\nfunction isObject(o) {\n  return Object.prototype.toString.call(o) === '[object Object]';\n}\n\nfunction isPlainObject(o) {\n  var ctor,prot;\n\n  if (isObject(o) === false) return false;\n\n  // If has modified constructor\n  ctor = o.constructor;\n  if (ctor === undefined) return true;\n\n  // If has modified prototype\n  prot = ctor.prototype;\n  if (isObject(prot) === false) return false;\n\n  // If constructor does not have an Object-specific method\n  if (prot.hasOwnProperty('isPrototypeOf') === false) {\n    return false;\n  }\n\n  // Most likely a plain Object\n  return true;\n}\n\nexports.isPlainObject = isPlainObject;\n\n\n/***/ }),\n\n/***/ 467:\n/***/ ((module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar Stream = _interopDefault(__webpack_require__(413));\nvar http = _interopDefault(__webpack_require__(605));\nvar Url = _interopDefault(__webpack_require__(835));\nvar https = _interopDefault(__webpack_require__(211));\nvar zlib = _interopDefault(__webpack_require__(761));\n\n// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js\n\n// fix for \"Readable\" isn't a named export issue\nconst Readable = Stream.Readable;\n\nconst BUFFER = Symbol('buffer');\nconst TYPE = Symbol('type');\n\nclass Blob {\n\tconstructor() {\n\t\tthis[TYPE] = '';\n\n\t\tconst blobParts = arguments[0];\n\t\tconst options = arguments[1];\n\n\t\tconst buffers = [];\n\t\tlet size = 0;\n\n\t\tif (blobParts) {\n\t\t\tconst a = blobParts;\n\t\t\tconst length = Number(a.length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tconst element = a[i];\n\t\t\t\tlet buffer;\n\t\t\t\tif (element instanceof Buffer) {\n\t\t\t\t\tbuffer = element;\n\t\t\t\t} else if (ArrayBuffer.isView(element)) {\n\t\t\t\t\tbuffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);\n\t\t\t\t} else if (element instanceof ArrayBuffer) {\n\t\t\t\t\tbuffer = Buffer.from(element);\n\t\t\t\t} else if (element instanceof Blob) {\n\t\t\t\t\tbuffer = element[BUFFER];\n\t\t\t\t} else {\n\t\t\t\t\tbuffer = Buffer.from(typeof element === 'string' ? element : String(element));\n\t\t\t\t}\n\t\t\t\tsize += buffer.length;\n\t\t\t\tbuffers.push(buffer);\n\t\t\t}\n\t\t}\n\n\t\tthis[BUFFER] = Buffer.concat(buffers);\n\n\t\tlet type = options && options.type !== undefined && String(options.type).toLowerCase();\n\t\tif (type && !/[^\\u0020-\\u007E]/.test(type)) {\n\t\t\tthis[TYPE] = type;\n\t\t}\n\t}\n\tget size() {\n\t\treturn this[BUFFER].length;\n\t}\n\tget type() {\n\t\treturn this[TYPE];\n\t}\n\ttext() {\n\t\treturn Promise.resolve(this[BUFFER].toString());\n\t}\n\tarrayBuffer() {\n\t\tconst buf = this[BUFFER];\n\t\tconst ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n\t\treturn Promise.resolve(ab);\n\t}\n\tstream() {\n\t\tconst readable = new Readable();\n\t\treadable._read = function () {};\n\t\treadable.push(this[BUFFER]);\n\t\treadable.push(null);\n\t\treturn readable;\n\t}\n\ttoString() {\n\t\treturn '[object Blob]';\n\t}\n\tslice() {\n\t\tconst size = this.size;\n\n\t\tconst start = arguments[0];\n\t\tconst end = arguments[1];\n\t\tlet relativeStart, relativeEnd;\n\t\tif (start === undefined) {\n\t\t\trelativeStart = 0;\n\t\t} else if (start < 0) {\n\t\t\trelativeStart = Math.max(size + start, 0);\n\t\t} else {\n\t\t\trelativeStart = Math.min(start, size);\n\t\t}\n\t\tif (end === undefined) {\n\t\t\trelativeEnd = size;\n\t\t} else if (end < 0) {\n\t\t\trelativeEnd = Math.max(size + end, 0);\n\t\t} else {\n\t\t\trelativeEnd = Math.min(end, size);\n\t\t}\n\t\tconst span = Math.max(relativeEnd - relativeStart, 0);\n\n\t\tconst buffer = this[BUFFER];\n\t\tconst slicedBuffer = buffer.slice(relativeStart, relativeStart + span);\n\t\tconst blob = new Blob([], { type: arguments[2] });\n\t\tblob[BUFFER] = slicedBuffer;\n\t\treturn blob;\n\t}\n}\n\nObject.defineProperties(Blob.prototype, {\n\tsize: { enumerable: true },\n\ttype: { enumerable: true },\n\tslice: { enumerable: true }\n});\n\nObject.defineProperty(Blob.prototype, Symbol.toStringTag, {\n\tvalue: 'Blob',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\n/**\n * fetch-error.js\n *\n * FetchError interface for operational errors\n */\n\n/**\n * Create FetchError instance\n *\n * @param   String      message      Error message for human\n * @param   String      type         Error type for machine\n * @param   String      systemError  For Node.js system error\n * @return  FetchError\n */\nfunction FetchError(message, type, systemError) {\n  Error.call(this, message);\n\n  this.message = message;\n  this.type = type;\n\n  // when err.type is `system`, err.code contains system error code\n  if (systemError) {\n    this.code = this.errno = systemError.code;\n  }\n\n  // hide custom error implementation details from end-users\n  Error.captureStackTrace(this, this.constructor);\n}\n\nFetchError.prototype = Object.create(Error.prototype);\nFetchError.prototype.constructor = FetchError;\nFetchError.prototype.name = 'FetchError';\n\nlet convert;\ntry {\n\tconvert = __webpack_require__(877).convert;\n} catch (e) {}\n\nconst INTERNALS = Symbol('Body internals');\n\n// fix an issue where \"PassThrough\" isn't a named export for node <10\nconst PassThrough = Stream.PassThrough;\n\n/**\n * Body mixin\n *\n * Ref: https://fetch.spec.whatwg.org/#body\n *\n * @param   Stream  body  Readable stream\n * @param   Object  opts  Response options\n * @return  Void\n */\nfunction Body(body) {\n\tvar _this = this;\n\n\tvar _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n\t    _ref$size = _ref.size;\n\n\tlet size = _ref$size === undefined ? 0 : _ref$size;\n\tvar _ref$timeout = _ref.timeout;\n\tlet timeout = _ref$timeout === undefined ? 0 : _ref$timeout;\n\n\tif (body == null) {\n\t\t// body is undefined or null\n\t\tbody = null;\n\t} else if (isURLSearchParams(body)) {\n\t\t// body is a URLSearchParams\n\t\tbody = Buffer.from(body.toString());\n\t} else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {\n\t\t// body is ArrayBuffer\n\t\tbody = Buffer.from(body);\n\t} else if (ArrayBuffer.isView(body)) {\n\t\t// body is ArrayBufferView\n\t\tbody = Buffer.from(body.buffer, body.byteOffset, body.byteLength);\n\t} else if (body instanceof Stream) ; else {\n\t\t// none of the above\n\t\t// coerce to string then buffer\n\t\tbody = Buffer.from(String(body));\n\t}\n\tthis[INTERNALS] = {\n\t\tbody,\n\t\tdisturbed: false,\n\t\terror: null\n\t};\n\tthis.size = size;\n\tthis.timeout = timeout;\n\n\tif (body instanceof Stream) {\n\t\tbody.on('error', function (err) {\n\t\t\tconst error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err);\n\t\t\t_this[INTERNALS].error = error;\n\t\t});\n\t}\n}\n\nBody.prototype = {\n\tget body() {\n\t\treturn this[INTERNALS].body;\n\t},\n\n\tget bodyUsed() {\n\t\treturn this[INTERNALS].disturbed;\n\t},\n\n\t/**\n  * Decode response as ArrayBuffer\n  *\n  * @return  Promise\n  */\n\tarrayBuffer() {\n\t\treturn consumeBody.call(this).then(function (buf) {\n\t\t\treturn buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n\t\t});\n\t},\n\n\t/**\n  * Return raw response as Blob\n  *\n  * @return Promise\n  */\n\tblob() {\n\t\tlet ct = this.headers && this.headers.get('content-type') || '';\n\t\treturn consumeBody.call(this).then(function (buf) {\n\t\t\treturn Object.assign(\n\t\t\t// Prevent copying\n\t\t\tnew Blob([], {\n\t\t\t\ttype: ct.toLowerCase()\n\t\t\t}), {\n\t\t\t\t[BUFFER]: buf\n\t\t\t});\n\t\t});\n\t},\n\n\t/**\n  * Decode response as json\n  *\n  * @return  Promise\n  */\n\tjson() {\n\t\tvar _this2 = this;\n\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buffer.toString());\n\t\t\t} catch (err) {\n\t\t\t\treturn Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n  * Decode response as text\n  *\n  * @return  Promise\n  */\n\ttext() {\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\treturn buffer.toString();\n\t\t});\n\t},\n\n\t/**\n  * Decode response as buffer (non-spec api)\n  *\n  * @return  Promise\n  */\n\tbuffer() {\n\t\treturn consumeBody.call(this);\n\t},\n\n\t/**\n  * Decode response as text, while automatically detecting the encoding and\n  * trying to decode to UTF-8 (non-spec api)\n  *\n  * @return  Promise\n  */\n\ttextConverted() {\n\t\tvar _this3 = this;\n\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\treturn convertBody(buffer, _this3.headers);\n\t\t});\n\t}\n};\n\n// In browsers, all properties are enumerable.\nObject.defineProperties(Body.prototype, {\n\tbody: { enumerable: true },\n\tbodyUsed: { enumerable: true },\n\tarrayBuffer: { enumerable: true },\n\tblob: { enumerable: true },\n\tjson: { enumerable: true },\n\ttext: { enumerable: true }\n});\n\nBody.mixIn = function (proto) {\n\tfor (const name of Object.getOwnPropertyNames(Body.prototype)) {\n\t\t// istanbul ignore else: future proof\n\t\tif (!(name in proto)) {\n\t\t\tconst desc = Object.getOwnPropertyDescriptor(Body.prototype, name);\n\t\t\tObject.defineProperty(proto, name, desc);\n\t\t}\n\t}\n};\n\n/**\n * Consume and convert an entire Body to a Buffer.\n *\n * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body\n *\n * @return  Promise\n */\nfunction consumeBody() {\n\tvar _this4 = this;\n\n\tif (this[INTERNALS].disturbed) {\n\t\treturn Body.Promise.reject(new TypeError(`body used already for: ${this.url}`));\n\t}\n\n\tthis[INTERNALS].disturbed = true;\n\n\tif (this[INTERNALS].error) {\n\t\treturn Body.Promise.reject(this[INTERNALS].error);\n\t}\n\n\tlet body = this.body;\n\n\t// body is null\n\tif (body === null) {\n\t\treturn Body.Promise.resolve(Buffer.alloc(0));\n\t}\n\n\t// body is blob\n\tif (isBlob(body)) {\n\t\tbody = body.stream();\n\t}\n\n\t// body is buffer\n\tif (Buffer.isBuffer(body)) {\n\t\treturn Body.Promise.resolve(body);\n\t}\n\n\t// istanbul ignore if: should never happen\n\tif (!(body instanceof Stream)) {\n\t\treturn Body.Promise.resolve(Buffer.alloc(0));\n\t}\n\n\t// body is stream\n\t// get ready to actually consume the body\n\tlet accum = [];\n\tlet accumBytes = 0;\n\tlet abort = false;\n\n\treturn new Body.Promise(function (resolve, reject) {\n\t\tlet resTimeout;\n\n\t\t// allow timeout on slow response body\n\t\tif (_this4.timeout) {\n\t\t\tresTimeout = setTimeout(function () {\n\t\t\t\tabort = true;\n\t\t\t\treject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout'));\n\t\t\t}, _this4.timeout);\n\t\t}\n\n\t\t// handle stream errors\n\t\tbody.on('error', function (err) {\n\t\t\tif (err.name === 'AbortError') {\n\t\t\t\t// if the request was aborted, reject with this Error\n\t\t\t\tabort = true;\n\t\t\t\treject(err);\n\t\t\t} else {\n\t\t\t\t// other errors, such as incorrect content-encoding\n\t\t\t\treject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err));\n\t\t\t}\n\t\t});\n\n\t\tbody.on('data', function (chunk) {\n\t\t\tif (abort || chunk === null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (_this4.size && accumBytes + chunk.length > _this4.size) {\n\t\t\t\tabort = true;\n\t\t\t\treject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size'));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\taccumBytes += chunk.length;\n\t\t\taccum.push(chunk);\n\t\t});\n\n\t\tbody.on('end', function () {\n\t\t\tif (abort) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tclearTimeout(resTimeout);\n\n\t\t\ttry {\n\t\t\t\tresolve(Buffer.concat(accum, accumBytes));\n\t\t\t} catch (err) {\n\t\t\t\t// handle streams that have accumulated too much data (issue #414)\n\t\t\t\treject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err));\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Detect buffer encoding and convert to target encoding\n * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding\n *\n * @param   Buffer  buffer    Incoming buffer\n * @param   String  encoding  Target encoding\n * @return  String\n */\nfunction convertBody(buffer, headers) {\n\tif (typeof convert !== 'function') {\n\t\tthrow new Error('The package `encoding` must be installed to use the textConverted() function');\n\t}\n\n\tconst ct = headers.get('content-type');\n\tlet charset = 'utf-8';\n\tlet res, str;\n\n\t// header\n\tif (ct) {\n\t\tres = /charset=([^;]*)/i.exec(ct);\n\t}\n\n\t// no charset in content type, peek at response body for at most 1024 bytes\n\tstr = buffer.slice(0, 1024).toString();\n\n\t// html5\n\tif (!res && str) {\n\t\tres = /<meta.+?charset=(['\"])(.+?)\\1/i.exec(str);\n\t}\n\n\t// html4\n\tif (!res && str) {\n\t\tres = /<meta[\\s]+?http-equiv=(['\"])content-type\\1[\\s]+?content=(['\"])(.+?)\\2/i.exec(str);\n\t\tif (!res) {\n\t\t\tres = /<meta[\\s]+?content=(['\"])(.+?)\\1[\\s]+?http-equiv=(['\"])content-type\\3/i.exec(str);\n\t\t\tif (res) {\n\t\t\t\tres.pop(); // drop last quote\n\t\t\t}\n\t\t}\n\n\t\tif (res) {\n\t\t\tres = /charset=(.*)/i.exec(res.pop());\n\t\t}\n\t}\n\n\t// xml\n\tif (!res && str) {\n\t\tres = /<\\?xml.+?encoding=(['\"])(.+?)\\1/i.exec(str);\n\t}\n\n\t// found charset\n\tif (res) {\n\t\tcharset = res.pop();\n\n\t\t// prevent decode issues when sites use incorrect encoding\n\t\t// ref: https://hsivonen.fi/encoding-menu/\n\t\tif (charset === 'gb2312' || charset === 'gbk') {\n\t\t\tcharset = 'gb18030';\n\t\t}\n\t}\n\n\t// turn raw buffers into a single utf-8 buffer\n\treturn convert(buffer, 'UTF-8', charset).toString();\n}\n\n/**\n * Detect a URLSearchParams object\n * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143\n *\n * @param   Object  obj     Object to detect by type or brand\n * @return  String\n */\nfunction isURLSearchParams(obj) {\n\t// Duck-typing as a necessary condition.\n\tif (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') {\n\t\treturn false;\n\t}\n\n\t// Brand-checking and more duck-typing as optional condition.\n\treturn obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';\n}\n\n/**\n * Check if `obj` is a W3C `Blob` object (which `File` inherits from)\n * @param  {*} obj\n * @return {boolean}\n */\nfunction isBlob(obj) {\n\treturn typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]);\n}\n\n/**\n * Clone body given Res/Req instance\n *\n * @param   Mixed  instance  Response or Request instance\n * @return  Mixed\n */\nfunction clone(instance) {\n\tlet p1, p2;\n\tlet body = instance.body;\n\n\t// don't allow cloning a used body\n\tif (instance.bodyUsed) {\n\t\tthrow new Error('cannot clone body after it is used');\n\t}\n\n\t// check that body is a stream and not form-data object\n\t// note: we can't clone the form-data object without having it as a dependency\n\tif (body instanceof Stream && typeof body.getBoundary !== 'function') {\n\t\t// tee instance body\n\t\tp1 = new PassThrough();\n\t\tp2 = new PassThrough();\n\t\tbody.pipe(p1);\n\t\tbody.pipe(p2);\n\t\t// set instance body to teed body and return the other teed body\n\t\tinstance[INTERNALS].body = p1;\n\t\tbody = p2;\n\t}\n\n\treturn body;\n}\n\n/**\n * Performs the operation \"extract a `Content-Type` value from |object|\" as\n * specified in the specification:\n * https://fetch.spec.whatwg.org/#concept-bodyinit-extract\n *\n * This function assumes that instance.body is present.\n *\n * @param   Mixed  instance  Any options.body input\n */\nfunction extractContentType(body) {\n\tif (body === null) {\n\t\t// body is null\n\t\treturn null;\n\t} else if (typeof body === 'string') {\n\t\t// body is string\n\t\treturn 'text/plain;charset=UTF-8';\n\t} else if (isURLSearchParams(body)) {\n\t\t// body is a URLSearchParams\n\t\treturn 'application/x-www-form-urlencoded;charset=UTF-8';\n\t} else if (isBlob(body)) {\n\t\t// body is blob\n\t\treturn body.type || null;\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\treturn null;\n\t} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {\n\t\t// body is ArrayBuffer\n\t\treturn null;\n\t} else if (ArrayBuffer.isView(body)) {\n\t\t// body is ArrayBufferView\n\t\treturn null;\n\t} else if (typeof body.getBoundary === 'function') {\n\t\t// detect form data input from form-data module\n\t\treturn `multipart/form-data;boundary=${body.getBoundary()}`;\n\t} else if (body instanceof Stream) {\n\t\t// body is stream\n\t\t// can't really do much about this\n\t\treturn null;\n\t} else {\n\t\t// Body constructor defaults other things to string\n\t\treturn 'text/plain;charset=UTF-8';\n\t}\n}\n\n/**\n * The Fetch Standard treats this as if \"total bytes\" is a property on the body.\n * For us, we have to explicitly get it with a function.\n *\n * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes\n *\n * @param   Body    instance   Instance of Body\n * @return  Number?            Number of bytes, or null if not possible\n */\nfunction getTotalBytes(instance) {\n\tconst body = instance.body;\n\n\n\tif (body === null) {\n\t\t// body is null\n\t\treturn 0;\n\t} else if (isBlob(body)) {\n\t\treturn body.size;\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\treturn body.length;\n\t} else if (body && typeof body.getLengthSync === 'function') {\n\t\t// detect form data input from form-data module\n\t\tif (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x\n\t\tbody.hasKnownLength && body.hasKnownLength()) {\n\t\t\t// 2.x\n\t\t\treturn body.getLengthSync();\n\t\t}\n\t\treturn null;\n\t} else {\n\t\t// body is stream\n\t\treturn null;\n\t}\n}\n\n/**\n * Write a Body to a Node.js WritableStream (e.g. http.Request) object.\n *\n * @param   Body    instance   Instance of Body\n * @return  Void\n */\nfunction writeToStream(dest, instance) {\n\tconst body = instance.body;\n\n\n\tif (body === null) {\n\t\t// body is null\n\t\tdest.end();\n\t} else if (isBlob(body)) {\n\t\tbody.stream().pipe(dest);\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\tdest.write(body);\n\t\tdest.end();\n\t} else {\n\t\t// body is stream\n\t\tbody.pipe(dest);\n\t}\n}\n\n// expose Promise\nBody.Promise = global.Promise;\n\n/**\n * headers.js\n *\n * Headers class offers convenient helpers\n */\n\nconst invalidTokenRegex = /[^\\^_`a-zA-Z\\-0-9!#$%&'*+.|~]/;\nconst invalidHeaderCharRegex = /[^\\t\\x20-\\x7e\\x80-\\xff]/;\n\nfunction validateName(name) {\n\tname = `${name}`;\n\tif (invalidTokenRegex.test(name) || name === '') {\n\t\tthrow new TypeError(`${name} is not a legal HTTP header name`);\n\t}\n}\n\nfunction validateValue(value) {\n\tvalue = `${value}`;\n\tif (invalidHeaderCharRegex.test(value)) {\n\t\tthrow new TypeError(`${value} is not a legal HTTP header value`);\n\t}\n}\n\n/**\n * Find the key in the map object given a header name.\n *\n * Returns undefined if not found.\n *\n * @param   String  name  Header name\n * @return  String|Undefined\n */\nfunction find(map, name) {\n\tname = name.toLowerCase();\n\tfor (const key in map) {\n\t\tif (key.toLowerCase() === name) {\n\t\t\treturn key;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nconst MAP = Symbol('map');\nclass Headers {\n\t/**\n  * Headers class\n  *\n  * @param   Object  headers  Response headers\n  * @return  Void\n  */\n\tconstructor() {\n\t\tlet init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;\n\n\t\tthis[MAP] = Object.create(null);\n\n\t\tif (init instanceof Headers) {\n\t\t\tconst rawHeaders = init.raw();\n\t\t\tconst headerNames = Object.keys(rawHeaders);\n\n\t\t\tfor (const headerName of headerNames) {\n\t\t\t\tfor (const value of rawHeaders[headerName]) {\n\t\t\t\t\tthis.append(headerName, value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// We don't worry about converting prop to ByteString here as append()\n\t\t// will handle it.\n\t\tif (init == null) ; else if (typeof init === 'object') {\n\t\t\tconst method = init[Symbol.iterator];\n\t\t\tif (method != null) {\n\t\t\t\tif (typeof method !== 'function') {\n\t\t\t\t\tthrow new TypeError('Header pairs must be iterable');\n\t\t\t\t}\n\n\t\t\t\t// sequence<sequence<ByteString>>\n\t\t\t\t// Note: per spec we have to first exhaust the lists then process them\n\t\t\t\tconst pairs = [];\n\t\t\t\tfor (const pair of init) {\n\t\t\t\t\tif (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {\n\t\t\t\t\t\tthrow new TypeError('Each header pair must be iterable');\n\t\t\t\t\t}\n\t\t\t\t\tpairs.push(Array.from(pair));\n\t\t\t\t}\n\n\t\t\t\tfor (const pair of pairs) {\n\t\t\t\t\tif (pair.length !== 2) {\n\t\t\t\t\t\tthrow new TypeError('Each header pair must be a name/value tuple');\n\t\t\t\t\t}\n\t\t\t\t\tthis.append(pair[0], pair[1]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// record<ByteString, ByteString>\n\t\t\t\tfor (const key of Object.keys(init)) {\n\t\t\t\t\tconst value = init[key];\n\t\t\t\t\tthis.append(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new TypeError('Provided initializer must be an object');\n\t\t}\n\t}\n\n\t/**\n  * Return combined header value given name\n  *\n  * @param   String  name  Header name\n  * @return  Mixed\n  */\n\tget(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key === undefined) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this[MAP][key].join(', ');\n\t}\n\n\t/**\n  * Iterate over all headers\n  *\n  * @param   Function  callback  Executed for each item with parameters (value, name, thisArg)\n  * @param   Boolean   thisArg   `this` context for callback function\n  * @return  Void\n  */\n\tforEach(callback) {\n\t\tlet thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;\n\n\t\tlet pairs = getHeaders(this);\n\t\tlet i = 0;\n\t\twhile (i < pairs.length) {\n\t\t\tvar _pairs$i = pairs[i];\n\t\t\tconst name = _pairs$i[0],\n\t\t\t      value = _pairs$i[1];\n\n\t\t\tcallback.call(thisArg, value, name, this);\n\t\t\tpairs = getHeaders(this);\n\t\t\ti++;\n\t\t}\n\t}\n\n\t/**\n  * Overwrite header values given name\n  *\n  * @param   String  name   Header name\n  * @param   String  value  Header value\n  * @return  Void\n  */\n\tset(name, value) {\n\t\tname = `${name}`;\n\t\tvalue = `${value}`;\n\t\tvalidateName(name);\n\t\tvalidateValue(value);\n\t\tconst key = find(this[MAP], name);\n\t\tthis[MAP][key !== undefined ? key : name] = [value];\n\t}\n\n\t/**\n  * Append a value onto existing header\n  *\n  * @param   String  name   Header name\n  * @param   String  value  Header value\n  * @return  Void\n  */\n\tappend(name, value) {\n\t\tname = `${name}`;\n\t\tvalue = `${value}`;\n\t\tvalidateName(name);\n\t\tvalidateValue(value);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key !== undefined) {\n\t\t\tthis[MAP][key].push(value);\n\t\t} else {\n\t\t\tthis[MAP][name] = [value];\n\t\t}\n\t}\n\n\t/**\n  * Check for header name existence\n  *\n  * @param   String   name  Header name\n  * @return  Boolean\n  */\n\thas(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\treturn find(this[MAP], name) !== undefined;\n\t}\n\n\t/**\n  * Delete all header values given name\n  *\n  * @param   String  name  Header name\n  * @return  Void\n  */\n\tdelete(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key !== undefined) {\n\t\t\tdelete this[MAP][key];\n\t\t}\n\t}\n\n\t/**\n  * Return raw headers (non-spec api)\n  *\n  * @return  Object\n  */\n\traw() {\n\t\treturn this[MAP];\n\t}\n\n\t/**\n  * Get an iterator on keys.\n  *\n  * @return  Iterator\n  */\n\tkeys() {\n\t\treturn createHeadersIterator(this, 'key');\n\t}\n\n\t/**\n  * Get an iterator on values.\n  *\n  * @return  Iterator\n  */\n\tvalues() {\n\t\treturn createHeadersIterator(this, 'value');\n\t}\n\n\t/**\n  * Get an iterator on entries.\n  *\n  * This is the default iterator of the Headers object.\n  *\n  * @return  Iterator\n  */\n\t[Symbol.iterator]() {\n\t\treturn createHeadersIterator(this, 'key+value');\n\t}\n}\nHeaders.prototype.entries = Headers.prototype[Symbol.iterator];\n\nObject.defineProperty(Headers.prototype, Symbol.toStringTag, {\n\tvalue: 'Headers',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nObject.defineProperties(Headers.prototype, {\n\tget: { enumerable: true },\n\tforEach: { enumerable: true },\n\tset: { enumerable: true },\n\tappend: { enumerable: true },\n\thas: { enumerable: true },\n\tdelete: { enumerable: true },\n\tkeys: { enumerable: true },\n\tvalues: { enumerable: true },\n\tentries: { enumerable: true }\n});\n\nfunction getHeaders(headers) {\n\tlet kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value';\n\n\tconst keys = Object.keys(headers[MAP]).sort();\n\treturn keys.map(kind === 'key' ? function (k) {\n\t\treturn k.toLowerCase();\n\t} : kind === 'value' ? function (k) {\n\t\treturn headers[MAP][k].join(', ');\n\t} : function (k) {\n\t\treturn [k.toLowerCase(), headers[MAP][k].join(', ')];\n\t});\n}\n\nconst INTERNAL = Symbol('internal');\n\nfunction createHeadersIterator(target, kind) {\n\tconst iterator = Object.create(HeadersIteratorPrototype);\n\titerator[INTERNAL] = {\n\t\ttarget,\n\t\tkind,\n\t\tindex: 0\n\t};\n\treturn iterator;\n}\n\nconst HeadersIteratorPrototype = Object.setPrototypeOf({\n\tnext() {\n\t\t// istanbul ignore if\n\t\tif (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {\n\t\t\tthrow new TypeError('Value of `this` is not a HeadersIterator');\n\t\t}\n\n\t\tvar _INTERNAL = this[INTERNAL];\n\t\tconst target = _INTERNAL.target,\n\t\t      kind = _INTERNAL.kind,\n\t\t      index = _INTERNAL.index;\n\n\t\tconst values = getHeaders(target, kind);\n\t\tconst len = values.length;\n\t\tif (index >= len) {\n\t\t\treturn {\n\t\t\t\tvalue: undefined,\n\t\t\t\tdone: true\n\t\t\t};\n\t\t}\n\n\t\tthis[INTERNAL].index = index + 1;\n\n\t\treturn {\n\t\t\tvalue: values[index],\n\t\t\tdone: false\n\t\t};\n\t}\n}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));\n\nObject.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {\n\tvalue: 'HeadersIterator',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\n/**\n * Export the Headers object in a form that Node.js can consume.\n *\n * @param   Headers  headers\n * @return  Object\n */\nfunction exportNodeCompatibleHeaders(headers) {\n\tconst obj = Object.assign({ __proto__: null }, headers[MAP]);\n\n\t// http.request() only supports string as Host header. This hack makes\n\t// specifying custom Host header possible.\n\tconst hostHeaderKey = find(headers[MAP], 'Host');\n\tif (hostHeaderKey !== undefined) {\n\t\tobj[hostHeaderKey] = obj[hostHeaderKey][0];\n\t}\n\n\treturn obj;\n}\n\n/**\n * Create a Headers object from an object of headers, ignoring those that do\n * not conform to HTTP grammar productions.\n *\n * @param   Object  obj  Object of headers\n * @return  Headers\n */\nfunction createHeadersLenient(obj) {\n\tconst headers = new Headers();\n\tfor (const name of Object.keys(obj)) {\n\t\tif (invalidTokenRegex.test(name)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (Array.isArray(obj[name])) {\n\t\t\tfor (const val of obj[name]) {\n\t\t\t\tif (invalidHeaderCharRegex.test(val)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (headers[MAP][name] === undefined) {\n\t\t\t\t\theaders[MAP][name] = [val];\n\t\t\t\t} else {\n\t\t\t\t\theaders[MAP][name].push(val);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (!invalidHeaderCharRegex.test(obj[name])) {\n\t\t\theaders[MAP][name] = [obj[name]];\n\t\t}\n\t}\n\treturn headers;\n}\n\nconst INTERNALS$1 = Symbol('Response internals');\n\n// fix an issue where \"STATUS_CODES\" aren't a named export for node <10\nconst STATUS_CODES = http.STATUS_CODES;\n\n/**\n * Response class\n *\n * @param   Stream  body  Readable stream\n * @param   Object  opts  Response options\n * @return  Void\n */\nclass Response {\n\tconstructor() {\n\t\tlet body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n\t\tlet opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n\t\tBody.call(this, body, opts);\n\n\t\tconst status = opts.status || 200;\n\t\tconst headers = new Headers(opts.headers);\n\n\t\tif (body != null && !headers.has('Content-Type')) {\n\t\t\tconst contentType = extractContentType(body);\n\t\t\tif (contentType) {\n\t\t\t\theaders.append('Content-Type', contentType);\n\t\t\t}\n\t\t}\n\n\t\tthis[INTERNALS$1] = {\n\t\t\turl: opts.url,\n\t\t\tstatus,\n\t\t\tstatusText: opts.statusText || STATUS_CODES[status],\n\t\t\theaders,\n\t\t\tcounter: opts.counter\n\t\t};\n\t}\n\n\tget url() {\n\t\treturn this[INTERNALS$1].url || '';\n\t}\n\n\tget status() {\n\t\treturn this[INTERNALS$1].status;\n\t}\n\n\t/**\n  * Convenience property representing if the request ended normally\n  */\n\tget ok() {\n\t\treturn this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300;\n\t}\n\n\tget redirected() {\n\t\treturn this[INTERNALS$1].counter > 0;\n\t}\n\n\tget statusText() {\n\t\treturn this[INTERNALS$1].statusText;\n\t}\n\n\tget headers() {\n\t\treturn this[INTERNALS$1].headers;\n\t}\n\n\t/**\n  * Clone this response\n  *\n  * @return  Response\n  */\n\tclone() {\n\t\treturn new Response(clone(this), {\n\t\t\turl: this.url,\n\t\t\tstatus: this.status,\n\t\t\tstatusText: this.statusText,\n\t\t\theaders: this.headers,\n\t\t\tok: this.ok,\n\t\t\tredirected: this.redirected\n\t\t});\n\t}\n}\n\nBody.mixIn(Response.prototype);\n\nObject.defineProperties(Response.prototype, {\n\turl: { enumerable: true },\n\tstatus: { enumerable: true },\n\tok: { enumerable: true },\n\tredirected: { enumerable: true },\n\tstatusText: { enumerable: true },\n\theaders: { enumerable: true },\n\tclone: { enumerable: true }\n});\n\nObject.defineProperty(Response.prototype, Symbol.toStringTag, {\n\tvalue: 'Response',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nconst INTERNALS$2 = Symbol('Request internals');\n\n// fix an issue where \"format\", \"parse\" aren't a named export for node <10\nconst parse_url = Url.parse;\nconst format_url = Url.format;\n\nconst streamDestructionSupported = 'destroy' in Stream.Readable.prototype;\n\n/**\n * Check if a value is an instance of Request.\n *\n * @param   Mixed   input\n * @return  Boolean\n */\nfunction isRequest(input) {\n\treturn typeof input === 'object' && typeof input[INTERNALS$2] === 'object';\n}\n\nfunction isAbortSignal(signal) {\n\tconst proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal);\n\treturn !!(proto && proto.constructor.name === 'AbortSignal');\n}\n\n/**\n * Request class\n *\n * @param   Mixed   input  Url or Request instance\n * @param   Object  init   Custom options\n * @return  Void\n */\nclass Request {\n\tconstructor(input) {\n\t\tlet init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n\t\tlet parsedURL;\n\n\t\t// normalize input\n\t\tif (!isRequest(input)) {\n\t\t\tif (input && input.href) {\n\t\t\t\t// in order to support Node.js' Url objects; though WHATWG's URL objects\n\t\t\t\t// will fall into this branch also (since their `toString()` will return\n\t\t\t\t// `href` property anyway)\n\t\t\t\tparsedURL = parse_url(input.href);\n\t\t\t} else {\n\t\t\t\t// coerce input to a string before attempting to parse\n\t\t\t\tparsedURL = parse_url(`${input}`);\n\t\t\t}\n\t\t\tinput = {};\n\t\t} else {\n\t\t\tparsedURL = parse_url(input.url);\n\t\t}\n\n\t\tlet method = init.method || input.method || 'GET';\n\t\tmethod = method.toUpperCase();\n\n\t\tif ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) {\n\t\t\tthrow new TypeError('Request with GET/HEAD method cannot have body');\n\t\t}\n\n\t\tlet inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null;\n\n\t\tBody.call(this, inputBody, {\n\t\t\ttimeout: init.timeout || input.timeout || 0,\n\t\t\tsize: init.size || input.size || 0\n\t\t});\n\n\t\tconst headers = new Headers(init.headers || input.headers || {});\n\n\t\tif (inputBody != null && !headers.has('Content-Type')) {\n\t\t\tconst contentType = extractContentType(inputBody);\n\t\t\tif (contentType) {\n\t\t\t\theaders.append('Content-Type', contentType);\n\t\t\t}\n\t\t}\n\n\t\tlet signal = isRequest(input) ? input.signal : null;\n\t\tif ('signal' in init) signal = init.signal;\n\n\t\tif (signal != null && !isAbortSignal(signal)) {\n\t\t\tthrow new TypeError('Expected signal to be an instanceof AbortSignal');\n\t\t}\n\n\t\tthis[INTERNALS$2] = {\n\t\t\tmethod,\n\t\t\tredirect: init.redirect || input.redirect || 'follow',\n\t\t\theaders,\n\t\t\tparsedURL,\n\t\t\tsignal\n\t\t};\n\n\t\t// node-fetch-only options\n\t\tthis.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;\n\t\tthis.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;\n\t\tthis.counter = init.counter || input.counter || 0;\n\t\tthis.agent = init.agent || input.agent;\n\t}\n\n\tget method() {\n\t\treturn this[INTERNALS$2].method;\n\t}\n\n\tget url() {\n\t\treturn format_url(this[INTERNALS$2].parsedURL);\n\t}\n\n\tget headers() {\n\t\treturn this[INTERNALS$2].headers;\n\t}\n\n\tget redirect() {\n\t\treturn this[INTERNALS$2].redirect;\n\t}\n\n\tget signal() {\n\t\treturn this[INTERNALS$2].signal;\n\t}\n\n\t/**\n  * Clone this request\n  *\n  * @return  Request\n  */\n\tclone() {\n\t\treturn new Request(this);\n\t}\n}\n\nBody.mixIn(Request.prototype);\n\nObject.defineProperty(Request.prototype, Symbol.toStringTag, {\n\tvalue: 'Request',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nObject.defineProperties(Request.prototype, {\n\tmethod: { enumerable: true },\n\turl: { enumerable: true },\n\theaders: { enumerable: true },\n\tredirect: { enumerable: true },\n\tclone: { enumerable: true },\n\tsignal: { enumerable: true }\n});\n\n/**\n * Convert a Request to Node.js http request options.\n *\n * @param   Request  A Request instance\n * @return  Object   The options object to be passed to http.request\n */\nfunction getNodeRequestOptions(request) {\n\tconst parsedURL = request[INTERNALS$2].parsedURL;\n\tconst headers = new Headers(request[INTERNALS$2].headers);\n\n\t// fetch step 1.3\n\tif (!headers.has('Accept')) {\n\t\theaders.set('Accept', '*/*');\n\t}\n\n\t// Basic fetch\n\tif (!parsedURL.protocol || !parsedURL.hostname) {\n\t\tthrow new TypeError('Only absolute URLs are supported');\n\t}\n\n\tif (!/^https?:$/.test(parsedURL.protocol)) {\n\t\tthrow new TypeError('Only HTTP(S) protocols are supported');\n\t}\n\n\tif (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) {\n\t\tthrow new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8');\n\t}\n\n\t// HTTP-network-or-cache fetch steps 2.4-2.7\n\tlet contentLengthValue = null;\n\tif (request.body == null && /^(POST|PUT)$/i.test(request.method)) {\n\t\tcontentLengthValue = '0';\n\t}\n\tif (request.body != null) {\n\t\tconst totalBytes = getTotalBytes(request);\n\t\tif (typeof totalBytes === 'number') {\n\t\t\tcontentLengthValue = String(totalBytes);\n\t\t}\n\t}\n\tif (contentLengthValue) {\n\t\theaders.set('Content-Length', contentLengthValue);\n\t}\n\n\t// HTTP-network-or-cache fetch step 2.11\n\tif (!headers.has('User-Agent')) {\n\t\theaders.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');\n\t}\n\n\t// HTTP-network-or-cache fetch step 2.15\n\tif (request.compress && !headers.has('Accept-Encoding')) {\n\t\theaders.set('Accept-Encoding', 'gzip,deflate');\n\t}\n\n\tlet agent = request.agent;\n\tif (typeof agent === 'function') {\n\t\tagent = agent(parsedURL);\n\t}\n\n\tif (!headers.has('Connection') && !agent) {\n\t\theaders.set('Connection', 'close');\n\t}\n\n\t// HTTP-network fetch step 4.2\n\t// chunked encoding is handled by Node.js\n\n\treturn Object.assign({}, parsedURL, {\n\t\tmethod: request.method,\n\t\theaders: exportNodeCompatibleHeaders(headers),\n\t\tagent\n\t});\n}\n\n/**\n * abort-error.js\n *\n * AbortError interface for cancelled requests\n */\n\n/**\n * Create AbortError instance\n *\n * @param   String      message      Error message for human\n * @return  AbortError\n */\nfunction AbortError(message) {\n  Error.call(this, message);\n\n  this.type = 'aborted';\n  this.message = message;\n\n  // hide custom error implementation details from end-users\n  Error.captureStackTrace(this, this.constructor);\n}\n\nAbortError.prototype = Object.create(Error.prototype);\nAbortError.prototype.constructor = AbortError;\nAbortError.prototype.name = 'AbortError';\n\n// fix an issue where \"PassThrough\", \"resolve\" aren't a named export for node <10\nconst PassThrough$1 = Stream.PassThrough;\nconst resolve_url = Url.resolve;\n\n/**\n * Fetch function\n *\n * @param   Mixed    url   Absolute url or Request instance\n * @param   Object   opts  Fetch options\n * @return  Promise\n */\nfunction fetch(url, opts) {\n\n\t// allow custom promise\n\tif (!fetch.Promise) {\n\t\tthrow new Error('native promise missing, set fetch.Promise to your favorite alternative');\n\t}\n\n\tBody.Promise = fetch.Promise;\n\n\t// wrap http.request into fetch\n\treturn new fetch.Promise(function (resolve, reject) {\n\t\t// build request object\n\t\tconst request = new Request(url, opts);\n\t\tconst options = getNodeRequestOptions(request);\n\n\t\tconst send = (options.protocol === 'https:' ? https : http).request;\n\t\tconst signal = request.signal;\n\n\t\tlet response = null;\n\n\t\tconst abort = function abort() {\n\t\t\tlet error = new AbortError('The user aborted a request.');\n\t\t\treject(error);\n\t\t\tif (request.body && request.body instanceof Stream.Readable) {\n\t\t\t\trequest.body.destroy(error);\n\t\t\t}\n\t\t\tif (!response || !response.body) return;\n\t\t\tresponse.body.emit('error', error);\n\t\t};\n\n\t\tif (signal && signal.aborted) {\n\t\t\tabort();\n\t\t\treturn;\n\t\t}\n\n\t\tconst abortAndFinalize = function abortAndFinalize() {\n\t\t\tabort();\n\t\t\tfinalize();\n\t\t};\n\n\t\t// send request\n\t\tconst req = send(options);\n\t\tlet reqTimeout;\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', abortAndFinalize);\n\t\t}\n\n\t\tfunction finalize() {\n\t\t\treq.abort();\n\t\t\tif (signal) signal.removeEventListener('abort', abortAndFinalize);\n\t\t\tclearTimeout(reqTimeout);\n\t\t}\n\n\t\tif (request.timeout) {\n\t\t\treq.once('socket', function (socket) {\n\t\t\t\treqTimeout = setTimeout(function () {\n\t\t\t\t\treject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));\n\t\t\t\t\tfinalize();\n\t\t\t\t}, request.timeout);\n\t\t\t});\n\t\t}\n\n\t\treq.on('error', function (err) {\n\t\t\treject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));\n\t\t\tfinalize();\n\t\t});\n\n\t\treq.on('response', function (res) {\n\t\t\tclearTimeout(reqTimeout);\n\n\t\t\tconst headers = createHeadersLenient(res.headers);\n\n\t\t\t// HTTP fetch step 5\n\t\t\tif (fetch.isRedirect(res.statusCode)) {\n\t\t\t\t// HTTP fetch step 5.2\n\t\t\t\tconst location = headers.get('Location');\n\n\t\t\t\t// HTTP fetch step 5.3\n\t\t\t\tconst locationURL = location === null ? null : resolve_url(request.url, location);\n\n\t\t\t\t// HTTP fetch step 5.5\n\t\t\t\tswitch (request.redirect) {\n\t\t\t\t\tcase 'error':\n\t\t\t\t\t\treject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase 'manual':\n\t\t\t\t\t\t// node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.\n\t\t\t\t\t\tif (locationURL !== null) {\n\t\t\t\t\t\t\t// handle corrupted header\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\theaders.set('Location', locationURL);\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t// istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request\n\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'follow':\n\t\t\t\t\t\t// HTTP-redirect fetch step 2\n\t\t\t\t\t\tif (locationURL === null) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 5\n\t\t\t\t\t\tif (request.counter >= request.follow) {\n\t\t\t\t\t\t\treject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));\n\t\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 6 (counter increment)\n\t\t\t\t\t\t// Create a new Request object.\n\t\t\t\t\t\tconst requestOpts = {\n\t\t\t\t\t\t\theaders: new Headers(request.headers),\n\t\t\t\t\t\t\tfollow: request.follow,\n\t\t\t\t\t\t\tcounter: request.counter + 1,\n\t\t\t\t\t\t\tagent: request.agent,\n\t\t\t\t\t\t\tcompress: request.compress,\n\t\t\t\t\t\t\tmethod: request.method,\n\t\t\t\t\t\t\tbody: request.body,\n\t\t\t\t\t\t\tsignal: request.signal,\n\t\t\t\t\t\t\ttimeout: request.timeout,\n\t\t\t\t\t\t\tsize: request.size\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 9\n\t\t\t\t\t\tif (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {\n\t\t\t\t\t\t\treject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));\n\t\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 11\n\t\t\t\t\t\tif (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {\n\t\t\t\t\t\t\trequestOpts.method = 'GET';\n\t\t\t\t\t\t\trequestOpts.body = undefined;\n\t\t\t\t\t\t\trequestOpts.headers.delete('content-length');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 15\n\t\t\t\t\t\tresolve(fetch(new Request(locationURL, requestOpts)));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// prepare response\n\t\t\tres.once('end', function () {\n\t\t\t\tif (signal) signal.removeEventListener('abort', abortAndFinalize);\n\t\t\t});\n\t\t\tlet body = res.pipe(new PassThrough$1());\n\n\t\t\tconst response_options = {\n\t\t\t\turl: request.url,\n\t\t\t\tstatus: res.statusCode,\n\t\t\t\tstatusText: res.statusMessage,\n\t\t\t\theaders: headers,\n\t\t\t\tsize: request.size,\n\t\t\t\ttimeout: request.timeout,\n\t\t\t\tcounter: request.counter\n\t\t\t};\n\n\t\t\t// HTTP-network fetch step 12.1.1.3\n\t\t\tconst codings = headers.get('Content-Encoding');\n\n\t\t\t// HTTP-network fetch step 12.1.1.4: handle content codings\n\n\t\t\t// in following scenarios we ignore compression support\n\t\t\t// 1. compression support is disabled\n\t\t\t// 2. HEAD request\n\t\t\t// 3. no Content-Encoding header\n\t\t\t// 4. no content response (204)\n\t\t\t// 5. content not modified response (304)\n\t\t\tif (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// For Node v6+\n\t\t\t// Be less strict when decoding compressed responses, since sometimes\n\t\t\t// servers send slightly invalid responses that are still accepted\n\t\t\t// by common browsers.\n\t\t\t// Always using Z_SYNC_FLUSH is what cURL does.\n\t\t\tconst zlibOptions = {\n\t\t\t\tflush: zlib.Z_SYNC_FLUSH,\n\t\t\t\tfinishFlush: zlib.Z_SYNC_FLUSH\n\t\t\t};\n\n\t\t\t// for gzip\n\t\t\tif (codings == 'gzip' || codings == 'x-gzip') {\n\t\t\t\tbody = body.pipe(zlib.createGunzip(zlibOptions));\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// for deflate\n\t\t\tif (codings == 'deflate' || codings == 'x-deflate') {\n\t\t\t\t// handle the infamous raw deflate response from old servers\n\t\t\t\t// a hack for old IIS and Apache servers\n\t\t\t\tconst raw = res.pipe(new PassThrough$1());\n\t\t\t\traw.once('data', function (chunk) {\n\t\t\t\t\t// see http://stackoverflow.com/questions/37519828\n\t\t\t\t\tif ((chunk[0] & 0x0F) === 0x08) {\n\t\t\t\t\t\tbody = body.pipe(zlib.createInflate());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbody = body.pipe(zlib.createInflateRaw());\n\t\t\t\t\t}\n\t\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\t\tresolve(response);\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// for br\n\t\t\tif (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') {\n\t\t\t\tbody = body.pipe(zlib.createBrotliDecompress());\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// otherwise, use response as-is\n\t\t\tresponse = new Response(body, response_options);\n\t\t\tresolve(response);\n\t\t});\n\n\t\twriteToStream(req, request);\n\t});\n}\n/**\n * Redirect code matching\n *\n * @param   Number   code  Status code\n * @return  Boolean\n */\nfetch.isRedirect = function (code) {\n\treturn code === 301 || code === 302 || code === 303 || code === 307 || code === 308;\n};\n\n// expose Promise\nfetch.Promise = global.Promise;\n\nmodule.exports = exports = fetch;\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.default = exports;\nexports.Headers = Headers;\nexports.Request = Request;\nexports.Response = Response;\nexports.FetchError = FetchError;\n\n\n/***/ }),\n\n/***/ 223:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nvar wrappy = __webpack_require__(940)\nmodule.exports = wrappy(once)\nmodule.exports.strict = wrappy(onceStrict)\n\nonce.proto = once(function () {\n  Object.defineProperty(Function.prototype, 'once', {\n    value: function () {\n      return once(this)\n    },\n    configurable: true\n  })\n\n  Object.defineProperty(Function.prototype, 'onceStrict', {\n    value: function () {\n      return onceStrict(this)\n    },\n    configurable: true\n  })\n})\n\nfunction once (fn) {\n  var f = function () {\n    if (f.called) return f.value\n    f.called = true\n    return f.value = fn.apply(this, arguments)\n  }\n  f.called = false\n  return f\n}\n\nfunction onceStrict (fn) {\n  var f = function () {\n    if (f.called)\n      throw new Error(f.onceError)\n    f.called = true\n    return f.value = fn.apply(this, arguments)\n  }\n  var name = fn.name || 'Function wrapped with `once`'\n  f.onceError = name + \" shouldn't be called more than once\"\n  f.called = false\n  return f\n}\n\n\n/***/ }),\n\n/***/ 294:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nmodule.exports = __webpack_require__(219);\n\n\n/***/ }),\n\n/***/ 219:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nvar net = __webpack_require__(631);\nvar tls = __webpack_require__(16);\nvar http = __webpack_require__(605);\nvar https = __webpack_require__(211);\nvar events = __webpack_require__(614);\nvar assert = __webpack_require__(357);\nvar util = __webpack_require__(669);\n\n\nexports.httpOverHttp = httpOverHttp;\nexports.httpsOverHttp = httpsOverHttp;\nexports.httpOverHttps = httpOverHttps;\nexports.httpsOverHttps = httpsOverHttps;\n\n\nfunction httpOverHttp(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = http.request;\n  return agent;\n}\n\nfunction httpsOverHttp(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = http.request;\n  agent.createSocket = createSecureSocket;\n  agent.defaultPort = 443;\n  return agent;\n}\n\nfunction httpOverHttps(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = https.request;\n  return agent;\n}\n\nfunction httpsOverHttps(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = https.request;\n  agent.createSocket = createSecureSocket;\n  agent.defaultPort = 443;\n  return agent;\n}\n\n\nfunction TunnelingAgent(options) {\n  var self = this;\n  self.options = options || {};\n  self.proxyOptions = self.options.proxy || {};\n  self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;\n  self.requests = [];\n  self.sockets = [];\n\n  self.on('free', function onFree(socket, host, port, localAddress) {\n    var options = toOptions(host, port, localAddress);\n    for (var i = 0, len = self.requests.length; i < len; ++i) {\n      var pending = self.requests[i];\n      if (pending.host === options.host && pending.port === options.port) {\n        // Detect the request to connect same origin server,\n        // reuse the connection.\n        self.requests.splice(i, 1);\n        pending.request.onSocket(socket);\n        return;\n      }\n    }\n    socket.destroy();\n    self.removeSocket(socket);\n  });\n}\nutil.inherits(TunnelingAgent, events.EventEmitter);\n\nTunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {\n  var self = this;\n  var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));\n\n  if (self.sockets.length >= this.maxSockets) {\n    // We are over limit so we'll add it to the queue.\n    self.requests.push(options);\n    return;\n  }\n\n  // If we are under maxSockets create a new one.\n  self.createSocket(options, function(socket) {\n    socket.on('free', onFree);\n    socket.on('close', onCloseOrRemove);\n    socket.on('agentRemove', onCloseOrRemove);\n    req.onSocket(socket);\n\n    function onFree() {\n      self.emit('free', socket, options);\n    }\n\n    function onCloseOrRemove(err) {\n      self.removeSocket(socket);\n      socket.removeListener('free', onFree);\n      socket.removeListener('close', onCloseOrRemove);\n      socket.removeListener('agentRemove', onCloseOrRemove);\n    }\n  });\n};\n\nTunnelingAgent.prototype.createSocket = function createSocket(options, cb) {\n  var self = this;\n  var placeholder = {};\n  self.sockets.push(placeholder);\n\n  var connectOptions = mergeOptions({}, self.proxyOptions, {\n    method: 'CONNECT',\n    path: options.host + ':' + options.port,\n    agent: false,\n    headers: {\n      host: options.host + ':' + options.port\n    }\n  });\n  if (options.localAddress) {\n    connectOptions.localAddress = options.localAddress;\n  }\n  if (connectOptions.proxyAuth) {\n    connectOptions.headers = connectOptions.headers || {};\n    connectOptions.headers['Proxy-Authorization'] = 'Basic ' +\n        new Buffer(connectOptions.proxyAuth).toString('base64');\n  }\n\n  debug('making CONNECT request');\n  var connectReq = self.request(connectOptions);\n  connectReq.useChunkedEncodingByDefault = false; // for v0.6\n  connectReq.once('response', onResponse); // for v0.6\n  connectReq.once('upgrade', onUpgrade);   // for v0.6\n  connectReq.once('connect', onConnect);   // for v0.7 or later\n  connectReq.once('error', onError);\n  connectReq.end();\n\n  function onResponse(res) {\n    // Very hacky. This is necessary to avoid http-parser leaks.\n    res.upgrade = true;\n  }\n\n  function onUpgrade(res, socket, head) {\n    // Hacky.\n    process.nextTick(function() {\n      onConnect(res, socket, head);\n    });\n  }\n\n  function onConnect(res, socket, head) {\n    connectReq.removeAllListeners();\n    socket.removeAllListeners();\n\n    if (res.statusCode !== 200) {\n      debug('tunneling socket could not be established, statusCode=%d',\n        res.statusCode);\n      socket.destroy();\n      var error = new Error('tunneling socket could not be established, ' +\n        'statusCode=' + res.statusCode);\n      error.code = 'ECONNRESET';\n      options.request.emit('error', error);\n      self.removeSocket(placeholder);\n      return;\n    }\n    if (head.length > 0) {\n      debug('got illegal response body from proxy');\n      socket.destroy();\n      var error = new Error('got illegal response body from proxy');\n      error.code = 'ECONNRESET';\n      options.request.emit('error', error);\n      self.removeSocket(placeholder);\n      return;\n    }\n    debug('tunneling connection has established');\n    self.sockets[self.sockets.indexOf(placeholder)] = socket;\n    return cb(socket);\n  }\n\n  function onError(cause) {\n    connectReq.removeAllListeners();\n\n    debug('tunneling socket could not be established, cause=%s\\n',\n          cause.message, cause.stack);\n    var error = new Error('tunneling socket could not be established, ' +\n                          'cause=' + cause.message);\n    error.code = 'ECONNRESET';\n    options.request.emit('error', error);\n    self.removeSocket(placeholder);\n  }\n};\n\nTunnelingAgent.prototype.removeSocket = function removeSocket(socket) {\n  var pos = this.sockets.indexOf(socket)\n  if (pos === -1) {\n    return;\n  }\n  this.sockets.splice(pos, 1);\n\n  var pending = this.requests.shift();\n  if (pending) {\n    // If we have pending requests and a socket gets closed a new one\n    // needs to be created to take over in the pool for the one that closed.\n    this.createSocket(pending, function(socket) {\n      pending.request.onSocket(socket);\n    });\n  }\n};\n\nfunction createSecureSocket(options, cb) {\n  var self = this;\n  TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {\n    var hostHeader = options.request.getHeader('host');\n    var tlsOptions = mergeOptions({}, self.options, {\n      socket: socket,\n      servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host\n    });\n\n    // 0 is dummy port for v0.6\n    var secureSocket = tls.connect(0, tlsOptions);\n    self.sockets[self.sockets.indexOf(socket)] = secureSocket;\n    cb(secureSocket);\n  });\n}\n\n\nfunction toOptions(host, port, localAddress) {\n  if (typeof host === 'string') { // since v0.10\n    return {\n      host: host,\n      port: port,\n      localAddress: localAddress\n    };\n  }\n  return host; // for v0.11 or later\n}\n\nfunction mergeOptions(target) {\n  for (var i = 1, len = arguments.length; i < len; ++i) {\n    var overrides = arguments[i];\n    if (typeof overrides === 'object') {\n      var keys = Object.keys(overrides);\n      for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {\n        var k = keys[j];\n        if (overrides[k] !== undefined) {\n          target[k] = overrides[k];\n        }\n      }\n    }\n  }\n  return target;\n}\n\n\nvar debug;\nif (process.env.NODE_DEBUG && /\\btunnel\\b/.test(process.env.NODE_DEBUG)) {\n  debug = function() {\n    var args = Array.prototype.slice.call(arguments);\n    if (typeof args[0] === 'string') {\n      args[0] = 'TUNNEL: ' + args[0];\n    } else {\n      args.unshift('TUNNEL:');\n    }\n    console.error.apply(console, args);\n  }\n} else {\n  debug = function() {};\n}\nexports.debug = debug; // for test\n\n\n/***/ }),\n\n/***/ 429:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction getUserAgent() {\n  if (typeof navigator === \"object\" && \"userAgent\" in navigator) {\n    return navigator.userAgent;\n  }\n\n  if (typeof process === \"object\" && \"version\" in process) {\n    return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`;\n  }\n\n  return \"<environment undetectable>\";\n}\n\nexports.getUserAgent = getUserAgent;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 940:\n/***/ ((module) => {\n\n// Returns a wrapper function that returns a wrapped callback\n// The wrapper function should do some stuff, and return a\n// presumably different callback function.\n// This makes sure that own properties are retained, so that\n// decorations and such are not lost along the way.\nmodule.exports = wrappy\nfunction wrappy (fn, cb) {\n  if (fn && cb) return wrappy(fn)(cb)\n\n  if (typeof fn !== 'function')\n    throw new TypeError('need wrapper function')\n\n  Object.keys(fn).forEach(function (k) {\n    wrapper[k] = fn[k]\n  })\n\n  return wrapper\n\n  function wrapper() {\n    var args = new Array(arguments.length)\n    for (var i = 0; i < args.length; i++) {\n      args[i] = arguments[i]\n    }\n    var ret = fn.apply(this, args)\n    var cb = args[args.length-1]\n    if (typeof ret === 'function' && ret !== cb) {\n      Object.keys(cb).forEach(function (k) {\n        ret[k] = cb[k]\n      })\n    }\n    return ret\n  }\n}\n\n\n/***/ }),\n\n/***/ 877:\n/***/ ((module) => {\n\nmodule.exports = eval(\"require\")(\"encoding\");\n\n\n/***/ }),\n\n/***/ 357:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"assert\");\n\n/***/ }),\n\n/***/ 614:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"events\");\n\n/***/ }),\n\n/***/ 747:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"fs\");\n\n/***/ }),\n\n/***/ 605:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"http\");\n\n/***/ }),\n\n/***/ 211:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"https\");\n\n/***/ }),\n\n/***/ 631:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"net\");\n\n/***/ }),\n\n/***/ 87:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"os\");\n\n/***/ }),\n\n/***/ 622:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"path\");\n\n/***/ }),\n\n/***/ 413:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"stream\");\n\n/***/ }),\n\n/***/ 16:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"tls\");\n\n/***/ }),\n\n/***/ 835:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"url\");\n\n/***/ }),\n\n/***/ 669:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"util\");\n\n/***/ }),\n\n/***/ 761:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"zlib\");\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\tvar threw = true;\n/******/ \t\ttry {\n/******/ \t\t\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/ \t\t\tthrew = false;\n/******/ \t\t} finally {\n/******/ \t\t\tif(threw) delete __webpack_module_cache__[moduleId];\n/******/ \t\t}\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat */\n/******/ \t\n/******/ \t__webpack_require__.ab = __dirname + \"/\";/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(932);\n/******/ })()\n;"
  },
  {
    "path": "pkg/runner/testdata/actions/node12/index.js",
    "content": "const core = require('@actions/core');\nconst github = require('@actions/github');\n\ntry {\n  // `who-to-greet` input defined in action metadata file\n  const nameToGreet = core.getInput('who-to-greet');\n  console.log(`Hello ${nameToGreet}!`);\n  const time = (new Date()).toTimeString();\n  core.setOutput(\"time\", time);\n  // Get the JSON webhook payload for the event that triggered the workflow\n  const payload = JSON.stringify(github.context.payload, undefined, 2)\n  console.log(`The event payload: ${payload}`);\n} catch (error) {\n  core.setFailed(error.message);\n}"
  },
  {
    "path": "pkg/runner/testdata/actions/node12/package.json",
    "content": "{\n  \"name\": \"node12\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"build\": \"ncc build index.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"@actions/core\": \"^1.2.6\",\n    \"@actions/github\": \"^4.0.0\"\n  },\n  \"devDependencies\": {\n    \"@vercel/ncc\": \"^0.24.1\"\n  },\n  \"engines\": {\n    \"node\": \">=12\"\n  }\n}\n"
  },
  {
    "path": "pkg/runner/testdata/actions/node16/README.md",
    "content": "### Updating\n\nIf an update to this app is required, it must be done manually via `npm run-script build` since the `node_modules` are not shared.\n"
  },
  {
    "path": "pkg/runner/testdata/actions/node16/action.yml",
    "content": "name: 'Hello World'\ndescription: 'Greet someone and record the time'\ninputs:\n  who-to-greet:  # id of input\n    description: 'Who to greet'\n    required: true\n    default: 'World'\noutputs:\n  time: # id of output\n    description: 'The time we greeted you'\nruns:\n  using: 'node16'\n  main: 'dist/index.js'\n"
  },
  {
    "path": "pkg/runner/testdata/actions/node16/dist/index.js",
    "content": "module.exports =\n/******/ (() => { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 2932:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\nconst core = __webpack_require__(2186);\nconst github = __webpack_require__(5438);\n\ntry {\n  // `who-to-greet` input defined in action metadata file\n  const nameToGreet = core.getInput('who-to-greet');\n  console.log(`Hello ${nameToGreet}!`);\n  const time = (new Date()).toTimeString();\n  core.setOutput(\"time\", time);\n  // Get the JSON webhook payload for the event that triggered the workflow\n  const payload = JSON.stringify(github.context.payload, undefined, 2)\n  console.log(`The event payload: ${payload}`);\n} catch (error) {\n  core.setFailed(error.message);\n}\n\n/***/ }),\n\n/***/ 7351:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.issue = exports.issueCommand = void 0;\nconst os = __importStar(__webpack_require__(2087));\nconst utils_1 = __webpack_require__(5278);\n/**\n * Commands\n *\n * Command Format:\n *   ::name key=value,key=value::message\n *\n * Examples:\n *   ::warning::This is the message\n *   ::set-env name=MY_VAR::some value\n */\nfunction issueCommand(command, properties, message) {\n    const cmd = new Command(command, properties, message);\n    process.stdout.write(cmd.toString() + os.EOL);\n}\nexports.issueCommand = issueCommand;\nfunction issue(name, message = '') {\n    issueCommand(name, {}, message);\n}\nexports.issue = issue;\nconst CMD_STRING = '::';\nclass Command {\n    constructor(command, properties, message) {\n        if (!command) {\n            command = 'missing.command';\n        }\n        this.command = command;\n        this.properties = properties;\n        this.message = message;\n    }\n    toString() {\n        let cmdStr = CMD_STRING + this.command;\n        if (this.properties && Object.keys(this.properties).length > 0) {\n            cmdStr += ' ';\n            let first = true;\n            for (const key in this.properties) {\n                if (this.properties.hasOwnProperty(key)) {\n                    const val = this.properties[key];\n                    if (val) {\n                        if (first) {\n                            first = false;\n                        }\n                        else {\n                            cmdStr += ',';\n                        }\n                        cmdStr += `${key}=${escapeProperty(val)}`;\n                    }\n                }\n            }\n        }\n        cmdStr += `${CMD_STRING}${escapeData(this.message)}`;\n        return cmdStr;\n    }\n}\nfunction escapeData(s) {\n    return utils_1.toCommandValue(s)\n        .replace(/%/g, '%25')\n        .replace(/\\r/g, '%0D')\n        .replace(/\\n/g, '%0A');\n}\nfunction escapeProperty(s) {\n    return utils_1.toCommandValue(s)\n        .replace(/%/g, '%25')\n        .replace(/\\r/g, '%0D')\n        .replace(/\\n/g, '%0A')\n        .replace(/:/g, '%3A')\n        .replace(/,/g, '%2C');\n}\n//# sourceMappingURL=command.js.map\n\n/***/ }),\n\n/***/ 2186:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;\nconst command_1 = __webpack_require__(7351);\nconst file_command_1 = __webpack_require__(717);\nconst utils_1 = __webpack_require__(5278);\nconst os = __importStar(__webpack_require__(2087));\nconst path = __importStar(__webpack_require__(5622));\nconst oidc_utils_1 = __webpack_require__(8041);\n/**\n * The code to exit an action\n */\nvar ExitCode;\n(function (ExitCode) {\n    /**\n     * A code indicating that the action was successful\n     */\n    ExitCode[ExitCode[\"Success\"] = 0] = \"Success\";\n    /**\n     * A code indicating that the action was a failure\n     */\n    ExitCode[ExitCode[\"Failure\"] = 1] = \"Failure\";\n})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));\n//-----------------------------------------------------------------------\n// Variables\n//-----------------------------------------------------------------------\n/**\n * Sets env variable for this action and future actions in the job\n * @param name the name of the variable to set\n * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction exportVariable(name, val) {\n    const convertedVal = utils_1.toCommandValue(val);\n    process.env[name] = convertedVal;\n    const filePath = process.env['GITHUB_ENV'] || '';\n    if (filePath) {\n        const delimiter = '_GitHubActionsFileCommandDelimeter_';\n        const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;\n        file_command_1.issueCommand('ENV', commandValue);\n    }\n    else {\n        command_1.issueCommand('set-env', { name }, convertedVal);\n    }\n}\nexports.exportVariable = exportVariable;\n/**\n * Registers a secret which will get masked from logs\n * @param secret value of the secret\n */\nfunction setSecret(secret) {\n    command_1.issueCommand('add-mask', {}, secret);\n}\nexports.setSecret = setSecret;\n/**\n * Prepends inputPath to the PATH (for this action and future actions)\n * @param inputPath\n */\nfunction addPath(inputPath) {\n    const filePath = process.env['GITHUB_PATH'] || '';\n    if (filePath) {\n        file_command_1.issueCommand('PATH', inputPath);\n    }\n    else {\n        command_1.issueCommand('add-path', {}, inputPath);\n    }\n    process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;\n}\nexports.addPath = addPath;\n/**\n * Gets the value of an input.\n * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed.\n * Returns an empty string if the value is not defined.\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   string\n */\nfunction getInput(name, options) {\n    const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';\n    if (options && options.required && !val) {\n        throw new Error(`Input required and not supplied: ${name}`);\n    }\n    if (options && options.trimWhitespace === false) {\n        return val;\n    }\n    return val.trim();\n}\nexports.getInput = getInput;\n/**\n * Gets the values of an multiline input.  Each value is also trimmed.\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   string[]\n *\n */\nfunction getMultilineInput(name, options) {\n    const inputs = getInput(name, options)\n        .split('\\n')\n        .filter(x => x !== '');\n    return inputs;\n}\nexports.getMultilineInput = getMultilineInput;\n/**\n * Gets the input value of the boolean type in the YAML 1.2 \"core schema\" specification.\n * Support boolean input list: `true | True | TRUE | false | False | FALSE` .\n * The return value is also in boolean type.\n * ref: https://yaml.org/spec/1.2/spec.html#id2804923\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   boolean\n */\nfunction getBooleanInput(name, options) {\n    const trueValue = ['true', 'True', 'TRUE'];\n    const falseValue = ['false', 'False', 'FALSE'];\n    const val = getInput(name, options);\n    if (trueValue.includes(val))\n        return true;\n    if (falseValue.includes(val))\n        return false;\n    throw new TypeError(`Input does not meet YAML 1.2 \"Core Schema\" specification: ${name}\\n` +\n        `Support boolean input list: \\`true | True | TRUE | false | False | FALSE\\``);\n}\nexports.getBooleanInput = getBooleanInput;\n/**\n * Sets the value of an output.\n *\n * @param     name     name of the output to set\n * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction setOutput(name, value) {\n    process.stdout.write(os.EOL);\n    command_1.issueCommand('set-output', { name }, value);\n}\nexports.setOutput = setOutput;\n/**\n * Enables or disables the echoing of commands into stdout for the rest of the step.\n * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.\n *\n */\nfunction setCommandEcho(enabled) {\n    command_1.issue('echo', enabled ? 'on' : 'off');\n}\nexports.setCommandEcho = setCommandEcho;\n//-----------------------------------------------------------------------\n// Results\n//-----------------------------------------------------------------------\n/**\n * Sets the action status to failed.\n * When the action exits it will be with an exit code of 1\n * @param message add error issue message\n */\nfunction setFailed(message) {\n    process.exitCode = ExitCode.Failure;\n    error(message);\n}\nexports.setFailed = setFailed;\n//-----------------------------------------------------------------------\n// Logging Commands\n//-----------------------------------------------------------------------\n/**\n * Gets whether Actions Step Debug is on or not\n */\nfunction isDebug() {\n    return process.env['RUNNER_DEBUG'] === '1';\n}\nexports.isDebug = isDebug;\n/**\n * Writes debug message to user log\n * @param message debug message\n */\nfunction debug(message) {\n    command_1.issueCommand('debug', {}, message);\n}\nexports.debug = debug;\n/**\n * Adds an error issue\n * @param message error issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction error(message, properties = {}) {\n    command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.error = error;\n/**\n * Adds a warning issue\n * @param message warning issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction warning(message, properties = {}) {\n    command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.warning = warning;\n/**\n * Adds a notice issue\n * @param message notice issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction notice(message, properties = {}) {\n    command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.notice = notice;\n/**\n * Writes info to log with console.log.\n * @param message info message\n */\nfunction info(message) {\n    process.stdout.write(message + os.EOL);\n}\nexports.info = info;\n/**\n * Begin an output group.\n *\n * Output until the next `groupEnd` will be foldable in this group\n *\n * @param name The name of the output group\n */\nfunction startGroup(name) {\n    command_1.issue('group', name);\n}\nexports.startGroup = startGroup;\n/**\n * End an output group.\n */\nfunction endGroup() {\n    command_1.issue('endgroup');\n}\nexports.endGroup = endGroup;\n/**\n * Wrap an asynchronous function call in a group.\n *\n * Returns the same type as the function itself.\n *\n * @param name The name of the group\n * @param fn The function to wrap in the group\n */\nfunction group(name, fn) {\n    return __awaiter(this, void 0, void 0, function* () {\n        startGroup(name);\n        let result;\n        try {\n            result = yield fn();\n        }\n        finally {\n            endGroup();\n        }\n        return result;\n    });\n}\nexports.group = group;\n//-----------------------------------------------------------------------\n// Wrapper action state\n//-----------------------------------------------------------------------\n/**\n * Saves state for current action, the state can only be retrieved by this action's post job execution.\n *\n * @param     name     name of the state to store\n * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction saveState(name, value) {\n    command_1.issueCommand('save-state', { name }, value);\n}\nexports.saveState = saveState;\n/**\n * Gets the value of an state set by this action's main execution.\n *\n * @param     name     name of the state to get\n * @returns   string\n */\nfunction getState(name) {\n    return process.env[`STATE_${name}`] || '';\n}\nexports.getState = getState;\nfunction getIDToken(aud) {\n    return __awaiter(this, void 0, void 0, function* () {\n        return yield oidc_utils_1.OidcClient.getIDToken(aud);\n    });\n}\nexports.getIDToken = getIDToken;\n//# sourceMappingURL=core.js.map\n\n/***/ }),\n\n/***/ 717:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// For internal use, subject to change.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.issueCommand = void 0;\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst fs = __importStar(__webpack_require__(5747));\nconst os = __importStar(__webpack_require__(2087));\nconst utils_1 = __webpack_require__(5278);\nfunction issueCommand(command, message) {\n    const filePath = process.env[`GITHUB_${command}`];\n    if (!filePath) {\n        throw new Error(`Unable to find environment variable for file command ${command}`);\n    }\n    if (!fs.existsSync(filePath)) {\n        throw new Error(`Missing file at path: ${filePath}`);\n    }\n    fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {\n        encoding: 'utf8'\n    });\n}\nexports.issueCommand = issueCommand;\n//# sourceMappingURL=file-command.js.map\n\n/***/ }),\n\n/***/ 8041:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.OidcClient = void 0;\nconst http_client_1 = __webpack_require__(9925);\nconst auth_1 = __webpack_require__(3702);\nconst core_1 = __webpack_require__(2186);\nclass OidcClient {\n    static createHttpClient(allowRetry = true, maxRetry = 10) {\n        const requestOptions = {\n            allowRetries: allowRetry,\n            maxRetries: maxRetry\n        };\n        return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions);\n    }\n    static getRequestToken() {\n        const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'];\n        if (!token) {\n            throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable');\n        }\n        return token;\n    }\n    static getIDTokenUrl() {\n        const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL'];\n        if (!runtimeUrl) {\n            throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable');\n        }\n        return runtimeUrl;\n    }\n    static getCall(id_token_url) {\n        var _a;\n        return __awaiter(this, void 0, void 0, function* () {\n            const httpclient = OidcClient.createHttpClient();\n            const res = yield httpclient\n                .getJson(id_token_url)\n                .catch(error => {\n                throw new Error(`Failed to get ID Token. \\n \n        Error Code : ${error.statusCode}\\n \n        Error Message: ${error.result.message}`);\n            });\n            const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value;\n            if (!id_token) {\n                throw new Error('Response json body do not have ID Token field');\n            }\n            return id_token;\n        });\n    }\n    static getIDToken(audience) {\n        return __awaiter(this, void 0, void 0, function* () {\n            try {\n                // New ID Token is requested from action service\n                let id_token_url = OidcClient.getIDTokenUrl();\n                if (audience) {\n                    const encodedAudience = encodeURIComponent(audience);\n                    id_token_url = `${id_token_url}&audience=${encodedAudience}`;\n                }\n                core_1.debug(`ID token url is ${id_token_url}`);\n                const id_token = yield OidcClient.getCall(id_token_url);\n                core_1.setSecret(id_token);\n                return id_token;\n            }\n            catch (error) {\n                throw new Error(`Error message: ${error.message}`);\n            }\n        });\n    }\n}\nexports.OidcClient = OidcClient;\n//# sourceMappingURL=oidc-utils.js.map\n\n/***/ }),\n\n/***/ 5278:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.toCommandProperties = exports.toCommandValue = void 0;\n/**\n * Sanitizes an input into a string so it can be passed into issueCommand safely\n * @param input input to sanitize into a string\n */\nfunction toCommandValue(input) {\n    if (input === null || input === undefined) {\n        return '';\n    }\n    else if (typeof input === 'string' || input instanceof String) {\n        return input;\n    }\n    return JSON.stringify(input);\n}\nexports.toCommandValue = toCommandValue;\n/**\n *\n * @param annotationProperties\n * @returns The command properties to send with the actual annotation command\n * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646\n */\nfunction toCommandProperties(annotationProperties) {\n    if (!Object.keys(annotationProperties).length) {\n        return {};\n    }\n    return {\n        title: annotationProperties.title,\n        file: annotationProperties.file,\n        line: annotationProperties.startLine,\n        endLine: annotationProperties.endLine,\n        col: annotationProperties.startColumn,\n        endColumn: annotationProperties.endColumn\n    };\n}\nexports.toCommandProperties = toCommandProperties;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 4087:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Context = void 0;\nconst fs_1 = __webpack_require__(5747);\nconst os_1 = __webpack_require__(2087);\nclass Context {\n    /**\n     * Hydrate the context from the environment\n     */\n    constructor() {\n        this.payload = {};\n        if (process.env.GITHUB_EVENT_PATH) {\n            if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) {\n                this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' }));\n            }\n            else {\n                const path = process.env.GITHUB_EVENT_PATH;\n                process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`);\n            }\n        }\n        this.eventName = process.env.GITHUB_EVENT_NAME;\n        this.sha = process.env.GITHUB_SHA;\n        this.ref = process.env.GITHUB_REF;\n        this.workflow = process.env.GITHUB_WORKFLOW;\n        this.action = process.env.GITHUB_ACTION;\n        this.actor = process.env.GITHUB_ACTOR;\n        this.job = process.env.GITHUB_JOB;\n        this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10);\n        this.runId = parseInt(process.env.GITHUB_RUN_ID, 10);\n    }\n    get issue() {\n        const payload = this.payload;\n        return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number });\n    }\n    get repo() {\n        if (process.env.GITHUB_REPOSITORY) {\n            const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');\n            return { owner, repo };\n        }\n        if (this.payload.repository) {\n            return {\n                owner: this.payload.repository.owner.login,\n                repo: this.payload.repository.name\n            };\n        }\n        throw new Error(\"context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'\");\n    }\n}\nexports.Context = Context;\n//# sourceMappingURL=context.js.map\n\n/***/ }),\n\n/***/ 5438:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getOctokit = exports.context = void 0;\nconst Context = __importStar(__webpack_require__(4087));\nconst utils_1 = __webpack_require__(3030);\nexports.context = new Context.Context();\n/**\n * Returns a hydrated octokit ready to use for GitHub Actions\n *\n * @param     token    the repo PAT or GITHUB_TOKEN\n * @param     options  other options to set\n */\nfunction getOctokit(token, options) {\n    return new utils_1.GitHub(utils_1.getOctokitOptions(token, options));\n}\nexports.getOctokit = getOctokit;\n//# sourceMappingURL=github.js.map\n\n/***/ }),\n\n/***/ 7914:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0;\nconst httpClient = __importStar(__webpack_require__(9925));\nfunction getAuthString(token, options) {\n    if (!token && !options.auth) {\n        throw new Error('Parameter token or opts.auth is required');\n    }\n    else if (token && options.auth) {\n        throw new Error('Parameters token and opts.auth may not both be specified');\n    }\n    return typeof options.auth === 'string' ? options.auth : `token ${token}`;\n}\nexports.getAuthString = getAuthString;\nfunction getProxyAgent(destinationUrl) {\n    const hc = new httpClient.HttpClient();\n    return hc.getAgent(destinationUrl);\n}\nexports.getProxyAgent = getProxyAgent;\nfunction getApiBaseUrl() {\n    return process.env['GITHUB_API_URL'] || 'https://api.github.com';\n}\nexports.getApiBaseUrl = getApiBaseUrl;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 3030:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getOctokitOptions = exports.GitHub = exports.context = void 0;\nconst Context = __importStar(__webpack_require__(4087));\nconst Utils = __importStar(__webpack_require__(7914));\n// octokit + plugins\nconst core_1 = __webpack_require__(6762);\nconst plugin_rest_endpoint_methods_1 = __webpack_require__(3044);\nconst plugin_paginate_rest_1 = __webpack_require__(4193);\nexports.context = new Context.Context();\nconst baseUrl = Utils.getApiBaseUrl();\nconst defaults = {\n    baseUrl,\n    request: {\n        agent: Utils.getProxyAgent(baseUrl)\n    }\n};\nexports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(defaults);\n/**\n * Convience function to correctly format Octokit Options to pass into the constructor.\n *\n * @param     token    the repo PAT or GITHUB_TOKEN\n * @param     options  other options to set\n */\nfunction getOctokitOptions(token, options) {\n    const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller\n    // Auth\n    const auth = Utils.getAuthString(token, opts);\n    if (auth) {\n        opts.auth = auth;\n    }\n    return opts;\n}\nexports.getOctokitOptions = getOctokitOptions;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 3702:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nclass BasicCredentialHandler {\n    constructor(username, password) {\n        this.username = username;\n        this.password = password;\n    }\n    prepareRequest(options) {\n        options.headers['Authorization'] =\n            'Basic ' +\n                Buffer.from(this.username + ':' + this.password).toString('base64');\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication(response) {\n        return false;\n    }\n    handleAuthentication(httpClient, requestInfo, objs) {\n        return null;\n    }\n}\nexports.BasicCredentialHandler = BasicCredentialHandler;\nclass BearerCredentialHandler {\n    constructor(token) {\n        this.token = token;\n    }\n    // currently implements pre-authorization\n    // TODO: support preAuth = false where it hooks on 401\n    prepareRequest(options) {\n        options.headers['Authorization'] = 'Bearer ' + this.token;\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication(response) {\n        return false;\n    }\n    handleAuthentication(httpClient, requestInfo, objs) {\n        return null;\n    }\n}\nexports.BearerCredentialHandler = BearerCredentialHandler;\nclass PersonalAccessTokenCredentialHandler {\n    constructor(token) {\n        this.token = token;\n    }\n    // currently implements pre-authorization\n    // TODO: support preAuth = false where it hooks on 401\n    prepareRequest(options) {\n        options.headers['Authorization'] =\n            'Basic ' + Buffer.from('PAT:' + this.token).toString('base64');\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication(response) {\n        return false;\n    }\n    handleAuthentication(httpClient, requestInfo, objs) {\n        return null;\n    }\n}\nexports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler;\n\n\n/***/ }),\n\n/***/ 9925:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst http = __webpack_require__(8605);\nconst https = __webpack_require__(7211);\nconst pm = __webpack_require__(6443);\nlet tunnel;\nvar HttpCodes;\n(function (HttpCodes) {\n    HttpCodes[HttpCodes[\"OK\"] = 200] = \"OK\";\n    HttpCodes[HttpCodes[\"MultipleChoices\"] = 300] = \"MultipleChoices\";\n    HttpCodes[HttpCodes[\"MovedPermanently\"] = 301] = \"MovedPermanently\";\n    HttpCodes[HttpCodes[\"ResourceMoved\"] = 302] = \"ResourceMoved\";\n    HttpCodes[HttpCodes[\"SeeOther\"] = 303] = \"SeeOther\";\n    HttpCodes[HttpCodes[\"NotModified\"] = 304] = \"NotModified\";\n    HttpCodes[HttpCodes[\"UseProxy\"] = 305] = \"UseProxy\";\n    HttpCodes[HttpCodes[\"SwitchProxy\"] = 306] = \"SwitchProxy\";\n    HttpCodes[HttpCodes[\"TemporaryRedirect\"] = 307] = \"TemporaryRedirect\";\n    HttpCodes[HttpCodes[\"PermanentRedirect\"] = 308] = \"PermanentRedirect\";\n    HttpCodes[HttpCodes[\"BadRequest\"] = 400] = \"BadRequest\";\n    HttpCodes[HttpCodes[\"Unauthorized\"] = 401] = \"Unauthorized\";\n    HttpCodes[HttpCodes[\"PaymentRequired\"] = 402] = \"PaymentRequired\";\n    HttpCodes[HttpCodes[\"Forbidden\"] = 403] = \"Forbidden\";\n    HttpCodes[HttpCodes[\"NotFound\"] = 404] = \"NotFound\";\n    HttpCodes[HttpCodes[\"MethodNotAllowed\"] = 405] = \"MethodNotAllowed\";\n    HttpCodes[HttpCodes[\"NotAcceptable\"] = 406] = \"NotAcceptable\";\n    HttpCodes[HttpCodes[\"ProxyAuthenticationRequired\"] = 407] = \"ProxyAuthenticationRequired\";\n    HttpCodes[HttpCodes[\"RequestTimeout\"] = 408] = \"RequestTimeout\";\n    HttpCodes[HttpCodes[\"Conflict\"] = 409] = \"Conflict\";\n    HttpCodes[HttpCodes[\"Gone\"] = 410] = \"Gone\";\n    HttpCodes[HttpCodes[\"TooManyRequests\"] = 429] = \"TooManyRequests\";\n    HttpCodes[HttpCodes[\"InternalServerError\"] = 500] = \"InternalServerError\";\n    HttpCodes[HttpCodes[\"NotImplemented\"] = 501] = \"NotImplemented\";\n    HttpCodes[HttpCodes[\"BadGateway\"] = 502] = \"BadGateway\";\n    HttpCodes[HttpCodes[\"ServiceUnavailable\"] = 503] = \"ServiceUnavailable\";\n    HttpCodes[HttpCodes[\"GatewayTimeout\"] = 504] = \"GatewayTimeout\";\n})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));\nvar Headers;\n(function (Headers) {\n    Headers[\"Accept\"] = \"accept\";\n    Headers[\"ContentType\"] = \"content-type\";\n})(Headers = exports.Headers || (exports.Headers = {}));\nvar MediaTypes;\n(function (MediaTypes) {\n    MediaTypes[\"ApplicationJson\"] = \"application/json\";\n})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {}));\n/**\n * Returns the proxy URL, depending upon the supplied url and proxy environment variables.\n * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com\n */\nfunction getProxyUrl(serverUrl) {\n    let proxyUrl = pm.getProxyUrl(new URL(serverUrl));\n    return proxyUrl ? proxyUrl.href : '';\n}\nexports.getProxyUrl = getProxyUrl;\nconst HttpRedirectCodes = [\n    HttpCodes.MovedPermanently,\n    HttpCodes.ResourceMoved,\n    HttpCodes.SeeOther,\n    HttpCodes.TemporaryRedirect,\n    HttpCodes.PermanentRedirect\n];\nconst HttpResponseRetryCodes = [\n    HttpCodes.BadGateway,\n    HttpCodes.ServiceUnavailable,\n    HttpCodes.GatewayTimeout\n];\nconst RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];\nconst ExponentialBackoffCeiling = 10;\nconst ExponentialBackoffTimeSlice = 5;\nclass HttpClientError extends Error {\n    constructor(message, statusCode) {\n        super(message);\n        this.name = 'HttpClientError';\n        this.statusCode = statusCode;\n        Object.setPrototypeOf(this, HttpClientError.prototype);\n    }\n}\nexports.HttpClientError = HttpClientError;\nclass HttpClientResponse {\n    constructor(message) {\n        this.message = message;\n    }\n    readBody() {\n        return new Promise(async (resolve, reject) => {\n            let output = Buffer.alloc(0);\n            this.message.on('data', (chunk) => {\n                output = Buffer.concat([output, chunk]);\n            });\n            this.message.on('end', () => {\n                resolve(output.toString());\n            });\n        });\n    }\n}\nexports.HttpClientResponse = HttpClientResponse;\nfunction isHttps(requestUrl) {\n    let parsedUrl = new URL(requestUrl);\n    return parsedUrl.protocol === 'https:';\n}\nexports.isHttps = isHttps;\nclass HttpClient {\n    constructor(userAgent, handlers, requestOptions) {\n        this._ignoreSslError = false;\n        this._allowRedirects = true;\n        this._allowRedirectDowngrade = false;\n        this._maxRedirects = 50;\n        this._allowRetries = false;\n        this._maxRetries = 1;\n        this._keepAlive = false;\n        this._disposed = false;\n        this.userAgent = userAgent;\n        this.handlers = handlers || [];\n        this.requestOptions = requestOptions;\n        if (requestOptions) {\n            if (requestOptions.ignoreSslError != null) {\n                this._ignoreSslError = requestOptions.ignoreSslError;\n            }\n            this._socketTimeout = requestOptions.socketTimeout;\n            if (requestOptions.allowRedirects != null) {\n                this._allowRedirects = requestOptions.allowRedirects;\n            }\n            if (requestOptions.allowRedirectDowngrade != null) {\n                this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade;\n            }\n            if (requestOptions.maxRedirects != null) {\n                this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);\n            }\n            if (requestOptions.keepAlive != null) {\n                this._keepAlive = requestOptions.keepAlive;\n            }\n            if (requestOptions.allowRetries != null) {\n                this._allowRetries = requestOptions.allowRetries;\n            }\n            if (requestOptions.maxRetries != null) {\n                this._maxRetries = requestOptions.maxRetries;\n            }\n        }\n    }\n    options(requestUrl, additionalHeaders) {\n        return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});\n    }\n    get(requestUrl, additionalHeaders) {\n        return this.request('GET', requestUrl, null, additionalHeaders || {});\n    }\n    del(requestUrl, additionalHeaders) {\n        return this.request('DELETE', requestUrl, null, additionalHeaders || {});\n    }\n    post(requestUrl, data, additionalHeaders) {\n        return this.request('POST', requestUrl, data, additionalHeaders || {});\n    }\n    patch(requestUrl, data, additionalHeaders) {\n        return this.request('PATCH', requestUrl, data, additionalHeaders || {});\n    }\n    put(requestUrl, data, additionalHeaders) {\n        return this.request('PUT', requestUrl, data, additionalHeaders || {});\n    }\n    head(requestUrl, additionalHeaders) {\n        return this.request('HEAD', requestUrl, null, additionalHeaders || {});\n    }\n    sendStream(verb, requestUrl, stream, additionalHeaders) {\n        return this.request(verb, requestUrl, stream, additionalHeaders);\n    }\n    /**\n     * Gets a typed object from an endpoint\n     * Be aware that not found returns a null.  Other errors (4xx, 5xx) reject the promise\n     */\n    async getJson(requestUrl, additionalHeaders = {}) {\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        let res = await this.get(requestUrl, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async postJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.post(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async putJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.put(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async patchJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.patch(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    /**\n     * Makes a raw http request.\n     * All other methods such as get, post, patch, and request ultimately call this.\n     * Prefer get, del, post and patch\n     */\n    async request(verb, requestUrl, data, headers) {\n        if (this._disposed) {\n            throw new Error('Client has already been disposed.');\n        }\n        let parsedUrl = new URL(requestUrl);\n        let info = this._prepareRequest(verb, parsedUrl, headers);\n        // Only perform retries on reads since writes may not be idempotent.\n        let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1\n            ? this._maxRetries + 1\n            : 1;\n        let numTries = 0;\n        let response;\n        while (numTries < maxTries) {\n            response = await this.requestRaw(info, data);\n            // Check if it's an authentication challenge\n            if (response &&\n                response.message &&\n                response.message.statusCode === HttpCodes.Unauthorized) {\n                let authenticationHandler;\n                for (let i = 0; i < this.handlers.length; i++) {\n                    if (this.handlers[i].canHandleAuthentication(response)) {\n                        authenticationHandler = this.handlers[i];\n                        break;\n                    }\n                }\n                if (authenticationHandler) {\n                    return authenticationHandler.handleAuthentication(this, info, data);\n                }\n                else {\n                    // We have received an unauthorized response but have no handlers to handle it.\n                    // Let the response return to the caller.\n                    return response;\n                }\n            }\n            let redirectsRemaining = this._maxRedirects;\n            while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 &&\n                this._allowRedirects &&\n                redirectsRemaining > 0) {\n                const redirectUrl = response.message.headers['location'];\n                if (!redirectUrl) {\n                    // if there's no location to redirect to, we won't\n                    break;\n                }\n                let parsedRedirectUrl = new URL(redirectUrl);\n                if (parsedUrl.protocol == 'https:' &&\n                    parsedUrl.protocol != parsedRedirectUrl.protocol &&\n                    !this._allowRedirectDowngrade) {\n                    throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');\n                }\n                // we need to finish reading the response before reassigning response\n                // which will leak the open socket.\n                await response.readBody();\n                // strip authorization header if redirected to a different hostname\n                if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {\n                    for (let header in headers) {\n                        // header names are case insensitive\n                        if (header.toLowerCase() === 'authorization') {\n                            delete headers[header];\n                        }\n                    }\n                }\n                // let's make the request with the new redirectUrl\n                info = this._prepareRequest(verb, parsedRedirectUrl, headers);\n                response = await this.requestRaw(info, data);\n                redirectsRemaining--;\n            }\n            if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) {\n                // If not a retry code, return immediately instead of retrying\n                return response;\n            }\n            numTries += 1;\n            if (numTries < maxTries) {\n                await response.readBody();\n                await this._performExponentialBackoff(numTries);\n            }\n        }\n        return response;\n    }\n    /**\n     * Needs to be called if keepAlive is set to true in request options.\n     */\n    dispose() {\n        if (this._agent) {\n            this._agent.destroy();\n        }\n        this._disposed = true;\n    }\n    /**\n     * Raw request.\n     * @param info\n     * @param data\n     */\n    requestRaw(info, data) {\n        return new Promise((resolve, reject) => {\n            let callbackForResult = function (err, res) {\n                if (err) {\n                    reject(err);\n                }\n                resolve(res);\n            };\n            this.requestRawWithCallback(info, data, callbackForResult);\n        });\n    }\n    /**\n     * Raw request with callback.\n     * @param info\n     * @param data\n     * @param onResult\n     */\n    requestRawWithCallback(info, data, onResult) {\n        let socket;\n        if (typeof data === 'string') {\n            info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');\n        }\n        let callbackCalled = false;\n        let handleResult = (err, res) => {\n            if (!callbackCalled) {\n                callbackCalled = true;\n                onResult(err, res);\n            }\n        };\n        let req = info.httpModule.request(info.options, (msg) => {\n            let res = new HttpClientResponse(msg);\n            handleResult(null, res);\n        });\n        req.on('socket', sock => {\n            socket = sock;\n        });\n        // If we ever get disconnected, we want the socket to timeout eventually\n        req.setTimeout(this._socketTimeout || 3 * 60000, () => {\n            if (socket) {\n                socket.end();\n            }\n            handleResult(new Error('Request timeout: ' + info.options.path), null);\n        });\n        req.on('error', function (err) {\n            // err has statusCode property\n            // res should have headers\n            handleResult(err, null);\n        });\n        if (data && typeof data === 'string') {\n            req.write(data, 'utf8');\n        }\n        if (data && typeof data !== 'string') {\n            data.on('close', function () {\n                req.end();\n            });\n            data.pipe(req);\n        }\n        else {\n            req.end();\n        }\n    }\n    /**\n     * Gets an http agent. This function is useful when you need an http agent that handles\n     * routing through a proxy server - depending upon the url and proxy environment variables.\n     * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com\n     */\n    getAgent(serverUrl) {\n        let parsedUrl = new URL(serverUrl);\n        return this._getAgent(parsedUrl);\n    }\n    _prepareRequest(method, requestUrl, headers) {\n        const info = {};\n        info.parsedUrl = requestUrl;\n        const usingSsl = info.parsedUrl.protocol === 'https:';\n        info.httpModule = usingSsl ? https : http;\n        const defaultPort = usingSsl ? 443 : 80;\n        info.options = {};\n        info.options.host = info.parsedUrl.hostname;\n        info.options.port = info.parsedUrl.port\n            ? parseInt(info.parsedUrl.port)\n            : defaultPort;\n        info.options.path =\n            (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');\n        info.options.method = method;\n        info.options.headers = this._mergeHeaders(headers);\n        if (this.userAgent != null) {\n            info.options.headers['user-agent'] = this.userAgent;\n        }\n        info.options.agent = this._getAgent(info.parsedUrl);\n        // gives handlers an opportunity to participate\n        if (this.handlers) {\n            this.handlers.forEach(handler => {\n                handler.prepareRequest(info.options);\n            });\n        }\n        return info;\n    }\n    _mergeHeaders(headers) {\n        const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});\n        if (this.requestOptions && this.requestOptions.headers) {\n            return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));\n        }\n        return lowercaseKeys(headers || {});\n    }\n    _getExistingOrDefaultHeader(additionalHeaders, header, _default) {\n        const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});\n        let clientHeader;\n        if (this.requestOptions && this.requestOptions.headers) {\n            clientHeader = lowercaseKeys(this.requestOptions.headers)[header];\n        }\n        return additionalHeaders[header] || clientHeader || _default;\n    }\n    _getAgent(parsedUrl) {\n        let agent;\n        let proxyUrl = pm.getProxyUrl(parsedUrl);\n        let useProxy = proxyUrl && proxyUrl.hostname;\n        if (this._keepAlive && useProxy) {\n            agent = this._proxyAgent;\n        }\n        if (this._keepAlive && !useProxy) {\n            agent = this._agent;\n        }\n        // if agent is already assigned use that agent.\n        if (!!agent) {\n            return agent;\n        }\n        const usingSsl = parsedUrl.protocol === 'https:';\n        let maxSockets = 100;\n        if (!!this.requestOptions) {\n            maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;\n        }\n        if (useProxy) {\n            // If using proxy, need tunnel\n            if (!tunnel) {\n                tunnel = __webpack_require__(4294);\n            }\n            const agentOptions = {\n                maxSockets: maxSockets,\n                keepAlive: this._keepAlive,\n                proxy: {\n                    ...((proxyUrl.username || proxyUrl.password) && {\n                        proxyAuth: `${proxyUrl.username}:${proxyUrl.password}`\n                    }),\n                    host: proxyUrl.hostname,\n                    port: proxyUrl.port\n                }\n            };\n            let tunnelAgent;\n            const overHttps = proxyUrl.protocol === 'https:';\n            if (usingSsl) {\n                tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;\n            }\n            else {\n                tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;\n            }\n            agent = tunnelAgent(agentOptions);\n            this._proxyAgent = agent;\n        }\n        // if reusing agent across request and tunneling agent isn't assigned create a new agent\n        if (this._keepAlive && !agent) {\n            const options = { keepAlive: this._keepAlive, maxSockets: maxSockets };\n            agent = usingSsl ? new https.Agent(options) : new http.Agent(options);\n            this._agent = agent;\n        }\n        // if not using private agent and tunnel agent isn't setup then use global agent\n        if (!agent) {\n            agent = usingSsl ? https.globalAgent : http.globalAgent;\n        }\n        if (usingSsl && this._ignoreSslError) {\n            // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process\n            // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options\n            // we have to cast it to any and change it directly\n            agent.options = Object.assign(agent.options || {}, {\n                rejectUnauthorized: false\n            });\n        }\n        return agent;\n    }\n    _performExponentialBackoff(retryNumber) {\n        retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);\n        const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);\n        return new Promise(resolve => setTimeout(() => resolve(), ms));\n    }\n    static dateTimeDeserializer(key, value) {\n        if (typeof value === 'string') {\n            let a = new Date(value);\n            if (!isNaN(a.valueOf())) {\n                return a;\n            }\n        }\n        return value;\n    }\n    async _processResponse(res, options) {\n        return new Promise(async (resolve, reject) => {\n            const statusCode = res.message.statusCode;\n            const response = {\n                statusCode: statusCode,\n                result: null,\n                headers: {}\n            };\n            // not found leads to null obj returned\n            if (statusCode == HttpCodes.NotFound) {\n                resolve(response);\n            }\n            let obj;\n            let contents;\n            // get the result from the body\n            try {\n                contents = await res.readBody();\n                if (contents && contents.length > 0) {\n                    if (options && options.deserializeDates) {\n                        obj = JSON.parse(contents, HttpClient.dateTimeDeserializer);\n                    }\n                    else {\n                        obj = JSON.parse(contents);\n                    }\n                    response.result = obj;\n                }\n                response.headers = res.message.headers;\n            }\n            catch (err) {\n                // Invalid resource (contents not json);  leaving result obj null\n            }\n            // note that 3xx redirects are handled by the http layer.\n            if (statusCode > 299) {\n                let msg;\n                // if exception/error in body, attempt to get better error\n                if (obj && obj.message) {\n                    msg = obj.message;\n                }\n                else if (contents && contents.length > 0) {\n                    // it may be the case that the exception is in the body message as string\n                    msg = contents;\n                }\n                else {\n                    msg = 'Failed request: (' + statusCode + ')';\n                }\n                let err = new HttpClientError(msg, statusCode);\n                err.result = response.result;\n                reject(err);\n            }\n            else {\n                resolve(response);\n            }\n        });\n    }\n}\nexports.HttpClient = HttpClient;\n\n\n/***/ }),\n\n/***/ 6443:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nfunction getProxyUrl(reqUrl) {\n    let usingSsl = reqUrl.protocol === 'https:';\n    let proxyUrl;\n    if (checkBypass(reqUrl)) {\n        return proxyUrl;\n    }\n    let proxyVar;\n    if (usingSsl) {\n        proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY'];\n    }\n    else {\n        proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY'];\n    }\n    if (proxyVar) {\n        proxyUrl = new URL(proxyVar);\n    }\n    return proxyUrl;\n}\nexports.getProxyUrl = getProxyUrl;\nfunction checkBypass(reqUrl) {\n    if (!reqUrl.hostname) {\n        return false;\n    }\n    let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';\n    if (!noProxy) {\n        return false;\n    }\n    // Determine the request port\n    let reqPort;\n    if (reqUrl.port) {\n        reqPort = Number(reqUrl.port);\n    }\n    else if (reqUrl.protocol === 'http:') {\n        reqPort = 80;\n    }\n    else if (reqUrl.protocol === 'https:') {\n        reqPort = 443;\n    }\n    // Format the request hostname and hostname with port\n    let upperReqHosts = [reqUrl.hostname.toUpperCase()];\n    if (typeof reqPort === 'number') {\n        upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);\n    }\n    // Compare request host against noproxy\n    for (let upperNoProxyItem of noProxy\n        .split(',')\n        .map(x => x.trim().toUpperCase())\n        .filter(x => x)) {\n        if (upperReqHosts.some(x => x === upperNoProxyItem)) {\n            return true;\n        }\n    }\n    return false;\n}\nexports.checkBypass = checkBypass;\n\n\n/***/ }),\n\n/***/ 334:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nconst REGEX_IS_INSTALLATION_LEGACY = /^v1\\./;\nconst REGEX_IS_INSTALLATION = /^ghs_/;\nconst REGEX_IS_USER_TO_SERVER = /^ghu_/;\nasync function auth(token) {\n  const isApp = token.split(/\\./).length === 3;\n  const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token);\n  const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token);\n  const tokenType = isApp ? \"app\" : isInstallation ? \"installation\" : isUserToServer ? \"user-to-server\" : \"oauth\";\n  return {\n    type: \"token\",\n    token: token,\n    tokenType\n  };\n}\n\n/**\n * Prefix token for usage in the Authorization header\n *\n * @param token OAuth token or JSON Web Token\n */\nfunction withAuthorizationPrefix(token) {\n  if (token.split(/\\./).length === 3) {\n    return `bearer ${token}`;\n  }\n\n  return `token ${token}`;\n}\n\nasync function hook(token, request, route, parameters) {\n  const endpoint = request.endpoint.merge(route, parameters);\n  endpoint.headers.authorization = withAuthorizationPrefix(token);\n  return request(endpoint);\n}\n\nconst createTokenAuth = function createTokenAuth(token) {\n  if (!token) {\n    throw new Error(\"[@octokit/auth-token] No token passed to createTokenAuth\");\n  }\n\n  if (typeof token !== \"string\") {\n    throw new Error(\"[@octokit/auth-token] Token passed to createTokenAuth is not a string\");\n  }\n\n  token = token.replace(/^(token|bearer) +/i, \"\");\n  return Object.assign(auth.bind(null, token), {\n    hook: hook.bind(null, token)\n  });\n};\n\nexports.createTokenAuth = createTokenAuth;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 6762:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar universalUserAgent = __webpack_require__(5030);\nvar beforeAfterHook = __webpack_require__(3682);\nvar request = __webpack_require__(6234);\nvar graphql = __webpack_require__(8467);\nvar authToken = __webpack_require__(334);\n\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n  if (source == null) return {};\n  var target = {};\n  var sourceKeys = Object.keys(source);\n  var key, i;\n\n  for (i = 0; i < sourceKeys.length; i++) {\n    key = sourceKeys[i];\n    if (excluded.indexOf(key) >= 0) continue;\n    target[key] = source[key];\n  }\n\n  return target;\n}\n\nfunction _objectWithoutProperties(source, excluded) {\n  if (source == null) return {};\n\n  var target = _objectWithoutPropertiesLoose(source, excluded);\n\n  var key, i;\n\n  if (Object.getOwnPropertySymbols) {\n    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n    for (i = 0; i < sourceSymbolKeys.length; i++) {\n      key = sourceSymbolKeys[i];\n      if (excluded.indexOf(key) >= 0) continue;\n      if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n      target[key] = source[key];\n    }\n  }\n\n  return target;\n}\n\nconst VERSION = \"3.5.1\";\n\nconst _excluded = [\"authStrategy\"];\nclass Octokit {\n  constructor(options = {}) {\n    const hook = new beforeAfterHook.Collection();\n    const requestDefaults = {\n      baseUrl: request.request.endpoint.DEFAULTS.baseUrl,\n      headers: {},\n      request: Object.assign({}, options.request, {\n        // @ts-ignore internal usage only, no need to type\n        hook: hook.bind(null, \"request\")\n      }),\n      mediaType: {\n        previews: [],\n        format: \"\"\n      }\n    }; // prepend default user agent with `options.userAgent` if set\n\n    requestDefaults.headers[\"user-agent\"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(\" \");\n\n    if (options.baseUrl) {\n      requestDefaults.baseUrl = options.baseUrl;\n    }\n\n    if (options.previews) {\n      requestDefaults.mediaType.previews = options.previews;\n    }\n\n    if (options.timeZone) {\n      requestDefaults.headers[\"time-zone\"] = options.timeZone;\n    }\n\n    this.request = request.request.defaults(requestDefaults);\n    this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults);\n    this.log = Object.assign({\n      debug: () => {},\n      info: () => {},\n      warn: console.warn.bind(console),\n      error: console.error.bind(console)\n    }, options.log);\n    this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance\n    //     is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered.\n    // (2) If only `options.auth` is set, use the default token authentication strategy.\n    // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance.\n    // TODO: type `options.auth` based on `options.authStrategy`.\n\n    if (!options.authStrategy) {\n      if (!options.auth) {\n        // (1)\n        this.auth = async () => ({\n          type: \"unauthenticated\"\n        });\n      } else {\n        // (2)\n        const auth = authToken.createTokenAuth(options.auth); // @ts-ignore  ¯\\_(ツ)_/¯\n\n        hook.wrap(\"request\", auth.hook);\n        this.auth = auth;\n      }\n    } else {\n      const {\n        authStrategy\n      } = options,\n            otherOptions = _objectWithoutProperties(options, _excluded);\n\n      const auth = authStrategy(Object.assign({\n        request: this.request,\n        log: this.log,\n        // we pass the current octokit instance as well as its constructor options\n        // to allow for authentication strategies that return a new octokit instance\n        // that shares the same internal state as the current one. The original\n        // requirement for this was the \"event-octokit\" authentication strategy\n        // of https://github.com/probot/octokit-auth-probot.\n        octokit: this,\n        octokitOptions: otherOptions\n      }, options.auth)); // @ts-ignore  ¯\\_(ツ)_/¯\n\n      hook.wrap(\"request\", auth.hook);\n      this.auth = auth;\n    } // apply plugins\n    // https://stackoverflow.com/a/16345172\n\n\n    const classConstructor = this.constructor;\n    classConstructor.plugins.forEach(plugin => {\n      Object.assign(this, plugin(this, options));\n    });\n  }\n\n  static defaults(defaults) {\n    const OctokitWithDefaults = class extends this {\n      constructor(...args) {\n        const options = args[0] || {};\n\n        if (typeof defaults === \"function\") {\n          super(defaults(options));\n          return;\n        }\n\n        super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? {\n          userAgent: `${options.userAgent} ${defaults.userAgent}`\n        } : null));\n      }\n\n    };\n    return OctokitWithDefaults;\n  }\n  /**\n   * Attach a plugin (or many) to your Octokit instance.\n   *\n   * @example\n   * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...)\n   */\n\n\n  static plugin(...newPlugins) {\n    var _a;\n\n    const currentPlugins = this.plugins;\n    const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a);\n    return NewOctokit;\n  }\n\n}\nOctokit.VERSION = VERSION;\nOctokit.plugins = [];\n\nexports.Octokit = Octokit;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 9440:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar isPlainObject = __webpack_require__(3287);\nvar universalUserAgent = __webpack_require__(5030);\n\nfunction lowercaseKeys(object) {\n  if (!object) {\n    return {};\n  }\n\n  return Object.keys(object).reduce((newObj, key) => {\n    newObj[key.toLowerCase()] = object[key];\n    return newObj;\n  }, {});\n}\n\nfunction mergeDeep(defaults, options) {\n  const result = Object.assign({}, defaults);\n  Object.keys(options).forEach(key => {\n    if (isPlainObject.isPlainObject(options[key])) {\n      if (!(key in defaults)) Object.assign(result, {\n        [key]: options[key]\n      });else result[key] = mergeDeep(defaults[key], options[key]);\n    } else {\n      Object.assign(result, {\n        [key]: options[key]\n      });\n    }\n  });\n  return result;\n}\n\nfunction removeUndefinedProperties(obj) {\n  for (const key in obj) {\n    if (obj[key] === undefined) {\n      delete obj[key];\n    }\n  }\n\n  return obj;\n}\n\nfunction merge(defaults, route, options) {\n  if (typeof route === \"string\") {\n    let [method, url] = route.split(\" \");\n    options = Object.assign(url ? {\n      method,\n      url\n    } : {\n      url: method\n    }, options);\n  } else {\n    options = Object.assign({}, route);\n  } // lowercase header names before merging with defaults to avoid duplicates\n\n\n  options.headers = lowercaseKeys(options.headers); // remove properties with undefined values before merging\n\n  removeUndefinedProperties(options);\n  removeUndefinedProperties(options.headers);\n  const mergedOptions = mergeDeep(defaults || {}, options); // mediaType.previews arrays are merged, instead of overwritten\n\n  if (defaults && defaults.mediaType.previews.length) {\n    mergedOptions.mediaType.previews = defaults.mediaType.previews.filter(preview => !mergedOptions.mediaType.previews.includes(preview)).concat(mergedOptions.mediaType.previews);\n  }\n\n  mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, \"\"));\n  return mergedOptions;\n}\n\nfunction addQueryParameters(url, parameters) {\n  const separator = /\\?/.test(url) ? \"&\" : \"?\";\n  const names = Object.keys(parameters);\n\n  if (names.length === 0) {\n    return url;\n  }\n\n  return url + separator + names.map(name => {\n    if (name === \"q\") {\n      return \"q=\" + parameters.q.split(\"+\").map(encodeURIComponent).join(\"+\");\n    }\n\n    return `${name}=${encodeURIComponent(parameters[name])}`;\n  }).join(\"&\");\n}\n\nconst urlVariableRegex = /\\{[^}]+\\}/g;\n\nfunction removeNonChars(variableName) {\n  return variableName.replace(/^\\W+|\\W+$/g, \"\").split(/,/);\n}\n\nfunction extractUrlVariableNames(url) {\n  const matches = url.match(urlVariableRegex);\n\n  if (!matches) {\n    return [];\n  }\n\n  return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);\n}\n\nfunction omit(object, keysToOmit) {\n  return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => {\n    obj[key] = object[key];\n    return obj;\n  }, {});\n}\n\n// Based on https://github.com/bramstein/url-template, licensed under BSD\n// TODO: create separate package.\n//\n// Copyright (c) 2012-2014, Bram Stein\n// All rights reserved.\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//  1. Redistributions of source code must retain the above copyright\n//     notice, this list of conditions and the following disclaimer.\n//  2. Redistributions in binary form must reproduce the above copyright\n//     notice, this list of conditions and the following disclaimer in the\n//     documentation and/or other materials provided with the distribution.\n//  3. The name of the author may not be used to endorse or promote products\n//     derived from this software without specific prior written permission.\n// THIS SOFTWARE IS PROVIDED BY THE AUTHOR \"AS IS\" AND ANY EXPRESS OR IMPLIED\n// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n// EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n/* istanbul ignore file */\nfunction encodeReserved(str) {\n  return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) {\n    if (!/%[0-9A-Fa-f]/.test(part)) {\n      part = encodeURI(part).replace(/%5B/g, \"[\").replace(/%5D/g, \"]\");\n    }\n\n    return part;\n  }).join(\"\");\n}\n\nfunction encodeUnreserved(str) {\n  return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {\n    return \"%\" + c.charCodeAt(0).toString(16).toUpperCase();\n  });\n}\n\nfunction encodeValue(operator, value, key) {\n  value = operator === \"+\" || operator === \"#\" ? encodeReserved(value) : encodeUnreserved(value);\n\n  if (key) {\n    return encodeUnreserved(key) + \"=\" + value;\n  } else {\n    return value;\n  }\n}\n\nfunction isDefined(value) {\n  return value !== undefined && value !== null;\n}\n\nfunction isKeyOperator(operator) {\n  return operator === \";\" || operator === \"&\" || operator === \"?\";\n}\n\nfunction getValues(context, operator, key, modifier) {\n  var value = context[key],\n      result = [];\n\n  if (isDefined(value) && value !== \"\") {\n    if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n      value = value.toString();\n\n      if (modifier && modifier !== \"*\") {\n        value = value.substring(0, parseInt(modifier, 10));\n      }\n\n      result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : \"\"));\n    } else {\n      if (modifier === \"*\") {\n        if (Array.isArray(value)) {\n          value.filter(isDefined).forEach(function (value) {\n            result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : \"\"));\n          });\n        } else {\n          Object.keys(value).forEach(function (k) {\n            if (isDefined(value[k])) {\n              result.push(encodeValue(operator, value[k], k));\n            }\n          });\n        }\n      } else {\n        const tmp = [];\n\n        if (Array.isArray(value)) {\n          value.filter(isDefined).forEach(function (value) {\n            tmp.push(encodeValue(operator, value));\n          });\n        } else {\n          Object.keys(value).forEach(function (k) {\n            if (isDefined(value[k])) {\n              tmp.push(encodeUnreserved(k));\n              tmp.push(encodeValue(operator, value[k].toString()));\n            }\n          });\n        }\n\n        if (isKeyOperator(operator)) {\n          result.push(encodeUnreserved(key) + \"=\" + tmp.join(\",\"));\n        } else if (tmp.length !== 0) {\n          result.push(tmp.join(\",\"));\n        }\n      }\n    }\n  } else {\n    if (operator === \";\") {\n      if (isDefined(value)) {\n        result.push(encodeUnreserved(key));\n      }\n    } else if (value === \"\" && (operator === \"&\" || operator === \"?\")) {\n      result.push(encodeUnreserved(key) + \"=\");\n    } else if (value === \"\") {\n      result.push(\"\");\n    }\n  }\n\n  return result;\n}\n\nfunction parseUrl(template) {\n  return {\n    expand: expand.bind(null, template)\n  };\n}\n\nfunction expand(template, context) {\n  var operators = [\"+\", \"#\", \".\", \"/\", \";\", \"?\", \"&\"];\n  return template.replace(/\\{([^\\{\\}]+)\\}|([^\\{\\}]+)/g, function (_, expression, literal) {\n    if (expression) {\n      let operator = \"\";\n      const values = [];\n\n      if (operators.indexOf(expression.charAt(0)) !== -1) {\n        operator = expression.charAt(0);\n        expression = expression.substr(1);\n      }\n\n      expression.split(/,/g).forEach(function (variable) {\n        var tmp = /([^:\\*]*)(?::(\\d+)|(\\*))?/.exec(variable);\n        values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3]));\n      });\n\n      if (operator && operator !== \"+\") {\n        var separator = \",\";\n\n        if (operator === \"?\") {\n          separator = \"&\";\n        } else if (operator !== \"#\") {\n          separator = operator;\n        }\n\n        return (values.length !== 0 ? operator : \"\") + values.join(separator);\n      } else {\n        return values.join(\",\");\n      }\n    } else {\n      return encodeReserved(literal);\n    }\n  });\n}\n\nfunction parse(options) {\n  // https://fetch.spec.whatwg.org/#methods\n  let method = options.method.toUpperCase(); // replace :varname with {varname} to make it RFC 6570 compatible\n\n  let url = (options.url || \"/\").replace(/:([a-z]\\w+)/g, \"{$1}\");\n  let headers = Object.assign({}, options.headers);\n  let body;\n  let parameters = omit(options, [\"method\", \"baseUrl\", \"url\", \"headers\", \"request\", \"mediaType\"]); // extract variable names from URL to calculate remaining variables later\n\n  const urlVariableNames = extractUrlVariableNames(url);\n  url = parseUrl(url).expand(parameters);\n\n  if (!/^http/.test(url)) {\n    url = options.baseUrl + url;\n  }\n\n  const omittedParameters = Object.keys(options).filter(option => urlVariableNames.includes(option)).concat(\"baseUrl\");\n  const remainingParameters = omit(parameters, omittedParameters);\n  const isBinaryRequest = /application\\/octet-stream/i.test(headers.accept);\n\n  if (!isBinaryRequest) {\n    if (options.mediaType.format) {\n      // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw\n      headers.accept = headers.accept.split(/,/).map(preview => preview.replace(/application\\/vnd(\\.\\w+)(\\.v3)?(\\.\\w+)?(\\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`)).join(\",\");\n    }\n\n    if (options.mediaType.previews.length) {\n      const previewsFromAcceptHeader = headers.accept.match(/[\\w-]+(?=-preview)/g) || [];\n      headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map(preview => {\n        const format = options.mediaType.format ? `.${options.mediaType.format}` : \"+json\";\n        return `application/vnd.github.${preview}-preview${format}`;\n      }).join(\",\");\n    }\n  } // for GET/HEAD requests, set URL query parameters from remaining parameters\n  // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters\n\n\n  if ([\"GET\", \"HEAD\"].includes(method)) {\n    url = addQueryParameters(url, remainingParameters);\n  } else {\n    if (\"data\" in remainingParameters) {\n      body = remainingParameters.data;\n    } else {\n      if (Object.keys(remainingParameters).length) {\n        body = remainingParameters;\n      } else {\n        headers[\"content-length\"] = 0;\n      }\n    }\n  } // default content-type for JSON if body is set\n\n\n  if (!headers[\"content-type\"] && typeof body !== \"undefined\") {\n    headers[\"content-type\"] = \"application/json; charset=utf-8\";\n  } // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.\n  // fetch does not allow to set `content-length` header, but we can set body to an empty string\n\n\n  if ([\"PATCH\", \"PUT\"].includes(method) && typeof body === \"undefined\") {\n    body = \"\";\n  } // Only return body/request keys if present\n\n\n  return Object.assign({\n    method,\n    url,\n    headers\n  }, typeof body !== \"undefined\" ? {\n    body\n  } : null, options.request ? {\n    request: options.request\n  } : null);\n}\n\nfunction endpointWithDefaults(defaults, route, options) {\n  return parse(merge(defaults, route, options));\n}\n\nfunction withDefaults(oldDefaults, newDefaults) {\n  const DEFAULTS = merge(oldDefaults, newDefaults);\n  const endpoint = endpointWithDefaults.bind(null, DEFAULTS);\n  return Object.assign(endpoint, {\n    DEFAULTS,\n    defaults: withDefaults.bind(null, DEFAULTS),\n    merge: merge.bind(null, DEFAULTS),\n    parse\n  });\n}\n\nconst VERSION = \"6.0.12\";\n\nconst userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`; // DEFAULTS has all properties set that EndpointOptions has, except url.\n// So we use RequestParameters and add method as additional required property.\n\nconst DEFAULTS = {\n  method: \"GET\",\n  baseUrl: \"https://api.github.com\",\n  headers: {\n    accept: \"application/vnd.github.v3+json\",\n    \"user-agent\": userAgent\n  },\n  mediaType: {\n    format: \"\",\n    previews: []\n  }\n};\n\nconst endpoint = withDefaults(null, DEFAULTS);\n\nexports.endpoint = endpoint;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 8467:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar request = __webpack_require__(6234);\nvar universalUserAgent = __webpack_require__(5030);\n\nconst VERSION = \"4.8.0\";\n\nfunction _buildMessageForResponseErrors(data) {\n  return `Request failed due to following response errors:\\n` + data.errors.map(e => ` - ${e.message}`).join(\"\\n\");\n}\n\nclass GraphqlResponseError extends Error {\n  constructor(request, headers, response) {\n    super(_buildMessageForResponseErrors(response));\n    this.request = request;\n    this.headers = headers;\n    this.response = response;\n    this.name = \"GraphqlResponseError\"; // Expose the errors and response data in their shorthand properties.\n\n    this.errors = response.errors;\n    this.data = response.data; // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n  }\n\n}\n\nconst NON_VARIABLE_OPTIONS = [\"method\", \"baseUrl\", \"url\", \"headers\", \"request\", \"query\", \"mediaType\"];\nconst FORBIDDEN_VARIABLE_OPTIONS = [\"query\", \"method\", \"url\"];\nconst GHES_V3_SUFFIX_REGEX = /\\/api\\/v3\\/?$/;\nfunction graphql(request, query, options) {\n  if (options) {\n    if (typeof query === \"string\" && \"query\" in options) {\n      return Promise.reject(new Error(`[@octokit/graphql] \"query\" cannot be used as variable name`));\n    }\n\n    for (const key in options) {\n      if (!FORBIDDEN_VARIABLE_OPTIONS.includes(key)) continue;\n      return Promise.reject(new Error(`[@octokit/graphql] \"${key}\" cannot be used as variable name`));\n    }\n  }\n\n  const parsedOptions = typeof query === \"string\" ? Object.assign({\n    query\n  }, options) : query;\n  const requestOptions = Object.keys(parsedOptions).reduce((result, key) => {\n    if (NON_VARIABLE_OPTIONS.includes(key)) {\n      result[key] = parsedOptions[key];\n      return result;\n    }\n\n    if (!result.variables) {\n      result.variables = {};\n    }\n\n    result.variables[key] = parsedOptions[key];\n    return result;\n  }, {}); // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix\n  // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451\n\n  const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;\n\n  if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {\n    requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, \"/api/graphql\");\n  }\n\n  return request(requestOptions).then(response => {\n    if (response.data.errors) {\n      const headers = {};\n\n      for (const key of Object.keys(response.headers)) {\n        headers[key] = response.headers[key];\n      }\n\n      throw new GraphqlResponseError(requestOptions, headers, response.data);\n    }\n\n    return response.data.data;\n  });\n}\n\nfunction withDefaults(request$1, newDefaults) {\n  const newRequest = request$1.defaults(newDefaults);\n\n  const newApi = (query, options) => {\n    return graphql(newRequest, query, options);\n  };\n\n  return Object.assign(newApi, {\n    defaults: withDefaults.bind(null, newRequest),\n    endpoint: request.request.endpoint\n  });\n}\n\nconst graphql$1 = withDefaults(request.request, {\n  headers: {\n    \"user-agent\": `octokit-graphql.js/${VERSION} ${universalUserAgent.getUserAgent()}`\n  },\n  method: \"POST\",\n  url: \"/graphql\"\n});\nfunction withCustomRequest(customRequest) {\n  return withDefaults(customRequest, {\n    method: \"POST\",\n    url: \"/graphql\"\n  });\n}\n\nexports.GraphqlResponseError = GraphqlResponseError;\nexports.graphql = graphql$1;\nexports.withCustomRequest = withCustomRequest;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 4193:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nconst VERSION = \"2.17.0\";\n\nfunction ownKeys(object, enumerableOnly) {\n  var keys = Object.keys(object);\n\n  if (Object.getOwnPropertySymbols) {\n    var symbols = Object.getOwnPropertySymbols(object);\n\n    if (enumerableOnly) {\n      symbols = symbols.filter(function (sym) {\n        return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n      });\n    }\n\n    keys.push.apply(keys, symbols);\n  }\n\n  return keys;\n}\n\nfunction _objectSpread2(target) {\n  for (var i = 1; i < arguments.length; i++) {\n    var source = arguments[i] != null ? arguments[i] : {};\n\n    if (i % 2) {\n      ownKeys(Object(source), true).forEach(function (key) {\n        _defineProperty(target, key, source[key]);\n      });\n    } else if (Object.getOwnPropertyDescriptors) {\n      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n    } else {\n      ownKeys(Object(source)).forEach(function (key) {\n        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n      });\n    }\n  }\n\n  return target;\n}\n\nfunction _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\n/**\n * Some “list” response that can be paginated have a different response structure\n *\n * They have a `total_count` key in the response (search also has `incomplete_results`,\n * /installation/repositories also has `repository_selection`), as well as a key with\n * the list of the items which name varies from endpoint to endpoint.\n *\n * Octokit normalizes these responses so that paginated results are always returned following\n * the same structure. One challenge is that if the list response has only one page, no Link\n * header is provided, so this header alone is not sufficient to check wether a response is\n * paginated or not.\n *\n * We check if a \"total_count\" key is present in the response data, but also make sure that\n * a \"url\" property is not, as the \"Get the combined status for a specific ref\" endpoint would\n * otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref\n */\nfunction normalizePaginatedListResponse(response) {\n  // endpoints can respond with 204 if repository is empty\n  if (!response.data) {\n    return _objectSpread2(_objectSpread2({}, response), {}, {\n      data: []\n    });\n  }\n\n  const responseNeedsNormalization = \"total_count\" in response.data && !(\"url\" in response.data);\n  if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way\n  // to retrieve the same information.\n\n  const incompleteResults = response.data.incomplete_results;\n  const repositorySelection = response.data.repository_selection;\n  const totalCount = response.data.total_count;\n  delete response.data.incomplete_results;\n  delete response.data.repository_selection;\n  delete response.data.total_count;\n  const namespaceKey = Object.keys(response.data)[0];\n  const data = response.data[namespaceKey];\n  response.data = data;\n\n  if (typeof incompleteResults !== \"undefined\") {\n    response.data.incomplete_results = incompleteResults;\n  }\n\n  if (typeof repositorySelection !== \"undefined\") {\n    response.data.repository_selection = repositorySelection;\n  }\n\n  response.data.total_count = totalCount;\n  return response;\n}\n\nfunction iterator(octokit, route, parameters) {\n  const options = typeof route === \"function\" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters);\n  const requestMethod = typeof route === \"function\" ? route : octokit.request;\n  const method = options.method;\n  const headers = options.headers;\n  let url = options.url;\n  return {\n    [Symbol.asyncIterator]: () => ({\n      async next() {\n        if (!url) return {\n          done: true\n        };\n\n        try {\n          const response = await requestMethod({\n            method,\n            url,\n            headers\n          });\n          const normalizedResponse = normalizePaginatedListResponse(response); // `response.headers.link` format:\n          // '<https://api.github.com/users/aseemk/followers?page=2>; rel=\"next\", <https://api.github.com/users/aseemk/followers?page=2>; rel=\"last\"'\n          // sets `url` to undefined if \"next\" URL is not present or `link` header is not set\n\n          url = ((normalizedResponse.headers.link || \"\").match(/<([^>]+)>;\\s*rel=\"next\"/) || [])[1];\n          return {\n            value: normalizedResponse\n          };\n        } catch (error) {\n          if (error.status !== 409) throw error;\n          url = \"\";\n          return {\n            value: {\n              status: 200,\n              headers: {},\n              data: []\n            }\n          };\n        }\n      }\n\n    })\n  };\n}\n\nfunction paginate(octokit, route, parameters, mapFn) {\n  if (typeof parameters === \"function\") {\n    mapFn = parameters;\n    parameters = undefined;\n  }\n\n  return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);\n}\n\nfunction gather(octokit, results, iterator, mapFn) {\n  return iterator.next().then(result => {\n    if (result.done) {\n      return results;\n    }\n\n    let earlyExit = false;\n\n    function done() {\n      earlyExit = true;\n    }\n\n    results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data);\n\n    if (earlyExit) {\n      return results;\n    }\n\n    return gather(octokit, results, iterator, mapFn);\n  });\n}\n\nconst composePaginateRest = Object.assign(paginate, {\n  iterator\n});\n\nconst paginatingEndpoints = [\"GET /app/hook/deliveries\", \"GET /app/installations\", \"GET /applications/grants\", \"GET /authorizations\", \"GET /enterprises/{enterprise}/actions/permissions/organizations\", \"GET /enterprises/{enterprise}/actions/runner-groups\", \"GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/organizations\", \"GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/runners\", \"GET /enterprises/{enterprise}/actions/runners\", \"GET /enterprises/{enterprise}/actions/runners/downloads\", \"GET /events\", \"GET /gists\", \"GET /gists/public\", \"GET /gists/starred\", \"GET /gists/{gist_id}/comments\", \"GET /gists/{gist_id}/commits\", \"GET /gists/{gist_id}/forks\", \"GET /installation/repositories\", \"GET /issues\", \"GET /marketplace_listing/plans\", \"GET /marketplace_listing/plans/{plan_id}/accounts\", \"GET /marketplace_listing/stubbed/plans\", \"GET /marketplace_listing/stubbed/plans/{plan_id}/accounts\", \"GET /networks/{owner}/{repo}/events\", \"GET /notifications\", \"GET /organizations\", \"GET /orgs/{org}/actions/permissions/repositories\", \"GET /orgs/{org}/actions/runner-groups\", \"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories\", \"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/runners\", \"GET /orgs/{org}/actions/runners\", \"GET /orgs/{org}/actions/runners/downloads\", \"GET /orgs/{org}/actions/secrets\", \"GET /orgs/{org}/actions/secrets/{secret_name}/repositories\", \"GET /orgs/{org}/blocks\", \"GET /orgs/{org}/credential-authorizations\", \"GET /orgs/{org}/events\", \"GET /orgs/{org}/failed_invitations\", \"GET /orgs/{org}/hooks\", \"GET /orgs/{org}/hooks/{hook_id}/deliveries\", \"GET /orgs/{org}/installations\", \"GET /orgs/{org}/invitations\", \"GET /orgs/{org}/invitations/{invitation_id}/teams\", \"GET /orgs/{org}/issues\", \"GET /orgs/{org}/members\", \"GET /orgs/{org}/migrations\", \"GET /orgs/{org}/migrations/{migration_id}/repositories\", \"GET /orgs/{org}/outside_collaborators\", \"GET /orgs/{org}/packages\", \"GET /orgs/{org}/projects\", \"GET /orgs/{org}/public_members\", \"GET /orgs/{org}/repos\", \"GET /orgs/{org}/secret-scanning/alerts\", \"GET /orgs/{org}/team-sync/groups\", \"GET /orgs/{org}/teams\", \"GET /orgs/{org}/teams/{team_slug}/discussions\", \"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments\", \"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions\", \"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions\", \"GET /orgs/{org}/teams/{team_slug}/invitations\", \"GET /orgs/{org}/teams/{team_slug}/members\", \"GET /orgs/{org}/teams/{team_slug}/projects\", \"GET /orgs/{org}/teams/{team_slug}/repos\", \"GET /orgs/{org}/teams/{team_slug}/team-sync/group-mappings\", \"GET /orgs/{org}/teams/{team_slug}/teams\", \"GET /projects/columns/{column_id}/cards\", \"GET /projects/{project_id}/collaborators\", \"GET /projects/{project_id}/columns\", \"GET /repos/{owner}/{repo}/actions/artifacts\", \"GET /repos/{owner}/{repo}/actions/runners\", \"GET /repos/{owner}/{repo}/actions/runners/downloads\", \"GET /repos/{owner}/{repo}/actions/runs\", \"GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts\", \"GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs\", \"GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs\", \"GET /repos/{owner}/{repo}/actions/secrets\", \"GET /repos/{owner}/{repo}/actions/workflows\", \"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs\", \"GET /repos/{owner}/{repo}/assignees\", \"GET /repos/{owner}/{repo}/autolinks\", \"GET /repos/{owner}/{repo}/branches\", \"GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations\", \"GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs\", \"GET /repos/{owner}/{repo}/code-scanning/alerts\", \"GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances\", \"GET /repos/{owner}/{repo}/code-scanning/analyses\", \"GET /repos/{owner}/{repo}/collaborators\", \"GET /repos/{owner}/{repo}/comments\", \"GET /repos/{owner}/{repo}/comments/{comment_id}/reactions\", \"GET /repos/{owner}/{repo}/commits\", \"GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head\", \"GET /repos/{owner}/{repo}/commits/{commit_sha}/comments\", \"GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls\", \"GET /repos/{owner}/{repo}/commits/{ref}/check-runs\", \"GET /repos/{owner}/{repo}/commits/{ref}/check-suites\", \"GET /repos/{owner}/{repo}/commits/{ref}/statuses\", \"GET /repos/{owner}/{repo}/contributors\", \"GET /repos/{owner}/{repo}/deployments\", \"GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses\", \"GET /repos/{owner}/{repo}/events\", \"GET /repos/{owner}/{repo}/forks\", \"GET /repos/{owner}/{repo}/git/matching-refs/{ref}\", \"GET /repos/{owner}/{repo}/hooks\", \"GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries\", \"GET /repos/{owner}/{repo}/invitations\", \"GET /repos/{owner}/{repo}/issues\", \"GET /repos/{owner}/{repo}/issues/comments\", \"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions\", \"GET /repos/{owner}/{repo}/issues/events\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/comments\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/events\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/labels\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/timeline\", \"GET /repos/{owner}/{repo}/keys\", \"GET /repos/{owner}/{repo}/labels\", \"GET /repos/{owner}/{repo}/milestones\", \"GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels\", \"GET /repos/{owner}/{repo}/notifications\", \"GET /repos/{owner}/{repo}/pages/builds\", \"GET /repos/{owner}/{repo}/projects\", \"GET /repos/{owner}/{repo}/pulls\", \"GET /repos/{owner}/{repo}/pulls/comments\", \"GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/comments\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/commits\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments\", \"GET /repos/{owner}/{repo}/releases\", \"GET /repos/{owner}/{repo}/releases/{release_id}/assets\", \"GET /repos/{owner}/{repo}/secret-scanning/alerts\", \"GET /repos/{owner}/{repo}/stargazers\", \"GET /repos/{owner}/{repo}/subscribers\", \"GET /repos/{owner}/{repo}/tags\", \"GET /repos/{owner}/{repo}/teams\", \"GET /repositories\", \"GET /repositories/{repository_id}/environments/{environment_name}/secrets\", \"GET /scim/v2/enterprises/{enterprise}/Groups\", \"GET /scim/v2/enterprises/{enterprise}/Users\", \"GET /scim/v2/organizations/{org}/Users\", \"GET /search/code\", \"GET /search/commits\", \"GET /search/issues\", \"GET /search/labels\", \"GET /search/repositories\", \"GET /search/topics\", \"GET /search/users\", \"GET /teams/{team_id}/discussions\", \"GET /teams/{team_id}/discussions/{discussion_number}/comments\", \"GET /teams/{team_id}/discussions/{discussion_number}/comments/{comment_number}/reactions\", \"GET /teams/{team_id}/discussions/{discussion_number}/reactions\", \"GET /teams/{team_id}/invitations\", \"GET /teams/{team_id}/members\", \"GET /teams/{team_id}/projects\", \"GET /teams/{team_id}/repos\", \"GET /teams/{team_id}/team-sync/group-mappings\", \"GET /teams/{team_id}/teams\", \"GET /user/blocks\", \"GET /user/emails\", \"GET /user/followers\", \"GET /user/following\", \"GET /user/gpg_keys\", \"GET /user/installations\", \"GET /user/installations/{installation_id}/repositories\", \"GET /user/issues\", \"GET /user/keys\", \"GET /user/marketplace_purchases\", \"GET /user/marketplace_purchases/stubbed\", \"GET /user/memberships/orgs\", \"GET /user/migrations\", \"GET /user/migrations/{migration_id}/repositories\", \"GET /user/orgs\", \"GET /user/packages\", \"GET /user/public_emails\", \"GET /user/repos\", \"GET /user/repository_invitations\", \"GET /user/starred\", \"GET /user/subscriptions\", \"GET /user/teams\", \"GET /users\", \"GET /users/{username}/events\", \"GET /users/{username}/events/orgs/{org}\", \"GET /users/{username}/events/public\", \"GET /users/{username}/followers\", \"GET /users/{username}/following\", \"GET /users/{username}/gists\", \"GET /users/{username}/gpg_keys\", \"GET /users/{username}/keys\", \"GET /users/{username}/orgs\", \"GET /users/{username}/packages\", \"GET /users/{username}/projects\", \"GET /users/{username}/received_events\", \"GET /users/{username}/received_events/public\", \"GET /users/{username}/repos\", \"GET /users/{username}/starred\", \"GET /users/{username}/subscriptions\"];\n\nfunction isPaginatingEndpoint(arg) {\n  if (typeof arg === \"string\") {\n    return paginatingEndpoints.includes(arg);\n  } else {\n    return false;\n  }\n}\n\n/**\n * @param octokit Octokit instance\n * @param options Options passed to Octokit constructor\n */\n\nfunction paginateRest(octokit) {\n  return {\n    paginate: Object.assign(paginate.bind(null, octokit), {\n      iterator: iterator.bind(null, octokit)\n    })\n  };\n}\npaginateRest.VERSION = VERSION;\n\nexports.composePaginateRest = composePaginateRest;\nexports.isPaginatingEndpoint = isPaginatingEndpoint;\nexports.paginateRest = paginateRest;\nexports.paginatingEndpoints = paginatingEndpoints;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 3044:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\nfunction ownKeys(object, enumerableOnly) {\n  var keys = Object.keys(object);\n\n  if (Object.getOwnPropertySymbols) {\n    var symbols = Object.getOwnPropertySymbols(object);\n    if (enumerableOnly) symbols = symbols.filter(function (sym) {\n      return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n    });\n    keys.push.apply(keys, symbols);\n  }\n\n  return keys;\n}\n\nfunction _objectSpread2(target) {\n  for (var i = 1; i < arguments.length; i++) {\n    var source = arguments[i] != null ? arguments[i] : {};\n\n    if (i % 2) {\n      ownKeys(Object(source), true).forEach(function (key) {\n        _defineProperty(target, key, source[key]);\n      });\n    } else if (Object.getOwnPropertyDescriptors) {\n      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n    } else {\n      ownKeys(Object(source)).forEach(function (key) {\n        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n      });\n    }\n  }\n\n  return target;\n}\n\nconst Endpoints = {\n  actions: {\n    addSelectedRepoToOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}\"],\n    cancelWorkflowRun: [\"POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel\"],\n    createOrUpdateEnvironmentSecret: [\"PUT /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}\"],\n    createOrUpdateOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}\"],\n    createOrUpdateRepoSecret: [\"PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    createRegistrationTokenForOrg: [\"POST /orgs/{org}/actions/runners/registration-token\"],\n    createRegistrationTokenForRepo: [\"POST /repos/{owner}/{repo}/actions/runners/registration-token\"],\n    createRemoveTokenForOrg: [\"POST /orgs/{org}/actions/runners/remove-token\"],\n    createRemoveTokenForRepo: [\"POST /repos/{owner}/{repo}/actions/runners/remove-token\"],\n    createWorkflowDispatch: [\"POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches\"],\n    deleteArtifact: [\"DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}\"],\n    deleteEnvironmentSecret: [\"DELETE /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}\"],\n    deleteOrgSecret: [\"DELETE /orgs/{org}/actions/secrets/{secret_name}\"],\n    deleteRepoSecret: [\"DELETE /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    deleteSelfHostedRunnerFromOrg: [\"DELETE /orgs/{org}/actions/runners/{runner_id}\"],\n    deleteSelfHostedRunnerFromRepo: [\"DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}\"],\n    deleteWorkflowRun: [\"DELETE /repos/{owner}/{repo}/actions/runs/{run_id}\"],\n    deleteWorkflowRunLogs: [\"DELETE /repos/{owner}/{repo}/actions/runs/{run_id}/logs\"],\n    disableSelectedRepositoryGithubActionsOrganization: [\"DELETE /orgs/{org}/actions/permissions/repositories/{repository_id}\"],\n    disableWorkflow: [\"PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable\"],\n    downloadArtifact: [\"GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}\"],\n    downloadJobLogsForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/jobs/{job_id}/logs\"],\n    downloadWorkflowRunLogs: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs\"],\n    enableSelectedRepositoryGithubActionsOrganization: [\"PUT /orgs/{org}/actions/permissions/repositories/{repository_id}\"],\n    enableWorkflow: [\"PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable\"],\n    getAllowedActionsOrganization: [\"GET /orgs/{org}/actions/permissions/selected-actions\"],\n    getAllowedActionsRepository: [\"GET /repos/{owner}/{repo}/actions/permissions/selected-actions\"],\n    getArtifact: [\"GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}\"],\n    getEnvironmentPublicKey: [\"GET /repositories/{repository_id}/environments/{environment_name}/secrets/public-key\"],\n    getEnvironmentSecret: [\"GET /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}\"],\n    getGithubActionsPermissionsOrganization: [\"GET /orgs/{org}/actions/permissions\"],\n    getGithubActionsPermissionsRepository: [\"GET /repos/{owner}/{repo}/actions/permissions\"],\n    getJobForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/jobs/{job_id}\"],\n    getOrgPublicKey: [\"GET /orgs/{org}/actions/secrets/public-key\"],\n    getOrgSecret: [\"GET /orgs/{org}/actions/secrets/{secret_name}\"],\n    getPendingDeploymentsForRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments\"],\n    getRepoPermissions: [\"GET /repos/{owner}/{repo}/actions/permissions\", {}, {\n      renamed: [\"actions\", \"getGithubActionsPermissionsRepository\"]\n    }],\n    getRepoPublicKey: [\"GET /repos/{owner}/{repo}/actions/secrets/public-key\"],\n    getRepoSecret: [\"GET /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    getReviewsForRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/approvals\"],\n    getSelfHostedRunnerForOrg: [\"GET /orgs/{org}/actions/runners/{runner_id}\"],\n    getSelfHostedRunnerForRepo: [\"GET /repos/{owner}/{repo}/actions/runners/{runner_id}\"],\n    getWorkflow: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}\"],\n    getWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}\"],\n    getWorkflowRunUsage: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/timing\"],\n    getWorkflowUsage: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing\"],\n    listArtifactsForRepo: [\"GET /repos/{owner}/{repo}/actions/artifacts\"],\n    listEnvironmentSecrets: [\"GET /repositories/{repository_id}/environments/{environment_name}/secrets\"],\n    listJobsForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs\"],\n    listOrgSecrets: [\"GET /orgs/{org}/actions/secrets\"],\n    listRepoSecrets: [\"GET /repos/{owner}/{repo}/actions/secrets\"],\n    listRepoWorkflows: [\"GET /repos/{owner}/{repo}/actions/workflows\"],\n    listRunnerApplicationsForOrg: [\"GET /orgs/{org}/actions/runners/downloads\"],\n    listRunnerApplicationsForRepo: [\"GET /repos/{owner}/{repo}/actions/runners/downloads\"],\n    listSelectedReposForOrgSecret: [\"GET /orgs/{org}/actions/secrets/{secret_name}/repositories\"],\n    listSelectedRepositoriesEnabledGithubActionsOrganization: [\"GET /orgs/{org}/actions/permissions/repositories\"],\n    listSelfHostedRunnersForOrg: [\"GET /orgs/{org}/actions/runners\"],\n    listSelfHostedRunnersForRepo: [\"GET /repos/{owner}/{repo}/actions/runners\"],\n    listWorkflowRunArtifacts: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts\"],\n    listWorkflowRuns: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs\"],\n    listWorkflowRunsForRepo: [\"GET /repos/{owner}/{repo}/actions/runs\"],\n    reRunWorkflow: [\"POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun\"],\n    removeSelectedRepoFromOrgSecret: [\"DELETE /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}\"],\n    reviewPendingDeploymentsForRun: [\"POST /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments\"],\n    setAllowedActionsOrganization: [\"PUT /orgs/{org}/actions/permissions/selected-actions\"],\n    setAllowedActionsRepository: [\"PUT /repos/{owner}/{repo}/actions/permissions/selected-actions\"],\n    setGithubActionsPermissionsOrganization: [\"PUT /orgs/{org}/actions/permissions\"],\n    setGithubActionsPermissionsRepository: [\"PUT /repos/{owner}/{repo}/actions/permissions\"],\n    setSelectedReposForOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}/repositories\"],\n    setSelectedRepositoriesEnabledGithubActionsOrganization: [\"PUT /orgs/{org}/actions/permissions/repositories\"]\n  },\n  activity: {\n    checkRepoIsStarredByAuthenticatedUser: [\"GET /user/starred/{owner}/{repo}\"],\n    deleteRepoSubscription: [\"DELETE /repos/{owner}/{repo}/subscription\"],\n    deleteThreadSubscription: [\"DELETE /notifications/threads/{thread_id}/subscription\"],\n    getFeeds: [\"GET /feeds\"],\n    getRepoSubscription: [\"GET /repos/{owner}/{repo}/subscription\"],\n    getThread: [\"GET /notifications/threads/{thread_id}\"],\n    getThreadSubscriptionForAuthenticatedUser: [\"GET /notifications/threads/{thread_id}/subscription\"],\n    listEventsForAuthenticatedUser: [\"GET /users/{username}/events\"],\n    listNotificationsForAuthenticatedUser: [\"GET /notifications\"],\n    listOrgEventsForAuthenticatedUser: [\"GET /users/{username}/events/orgs/{org}\"],\n    listPublicEvents: [\"GET /events\"],\n    listPublicEventsForRepoNetwork: [\"GET /networks/{owner}/{repo}/events\"],\n    listPublicEventsForUser: [\"GET /users/{username}/events/public\"],\n    listPublicOrgEvents: [\"GET /orgs/{org}/events\"],\n    listReceivedEventsForUser: [\"GET /users/{username}/received_events\"],\n    listReceivedPublicEventsForUser: [\"GET /users/{username}/received_events/public\"],\n    listRepoEvents: [\"GET /repos/{owner}/{repo}/events\"],\n    listRepoNotificationsForAuthenticatedUser: [\"GET /repos/{owner}/{repo}/notifications\"],\n    listReposStarredByAuthenticatedUser: [\"GET /user/starred\"],\n    listReposStarredByUser: [\"GET /users/{username}/starred\"],\n    listReposWatchedByUser: [\"GET /users/{username}/subscriptions\"],\n    listStargazersForRepo: [\"GET /repos/{owner}/{repo}/stargazers\"],\n    listWatchedReposForAuthenticatedUser: [\"GET /user/subscriptions\"],\n    listWatchersForRepo: [\"GET /repos/{owner}/{repo}/subscribers\"],\n    markNotificationsAsRead: [\"PUT /notifications\"],\n    markRepoNotificationsAsRead: [\"PUT /repos/{owner}/{repo}/notifications\"],\n    markThreadAsRead: [\"PATCH /notifications/threads/{thread_id}\"],\n    setRepoSubscription: [\"PUT /repos/{owner}/{repo}/subscription\"],\n    setThreadSubscription: [\"PUT /notifications/threads/{thread_id}/subscription\"],\n    starRepoForAuthenticatedUser: [\"PUT /user/starred/{owner}/{repo}\"],\n    unstarRepoForAuthenticatedUser: [\"DELETE /user/starred/{owner}/{repo}\"]\n  },\n  apps: {\n    addRepoToInstallation: [\"PUT /user/installations/{installation_id}/repositories/{repository_id}\"],\n    checkToken: [\"POST /applications/{client_id}/token\"],\n    createContentAttachment: [\"POST /content_references/{content_reference_id}/attachments\", {\n      mediaType: {\n        previews: [\"corsair\"]\n      }\n    }],\n    createFromManifest: [\"POST /app-manifests/{code}/conversions\"],\n    createInstallationAccessToken: [\"POST /app/installations/{installation_id}/access_tokens\"],\n    deleteAuthorization: [\"DELETE /applications/{client_id}/grant\"],\n    deleteInstallation: [\"DELETE /app/installations/{installation_id}\"],\n    deleteToken: [\"DELETE /applications/{client_id}/token\"],\n    getAuthenticated: [\"GET /app\"],\n    getBySlug: [\"GET /apps/{app_slug}\"],\n    getInstallation: [\"GET /app/installations/{installation_id}\"],\n    getOrgInstallation: [\"GET /orgs/{org}/installation\"],\n    getRepoInstallation: [\"GET /repos/{owner}/{repo}/installation\"],\n    getSubscriptionPlanForAccount: [\"GET /marketplace_listing/accounts/{account_id}\"],\n    getSubscriptionPlanForAccountStubbed: [\"GET /marketplace_listing/stubbed/accounts/{account_id}\"],\n    getUserInstallation: [\"GET /users/{username}/installation\"],\n    getWebhookConfigForApp: [\"GET /app/hook/config\"],\n    listAccountsForPlan: [\"GET /marketplace_listing/plans/{plan_id}/accounts\"],\n    listAccountsForPlanStubbed: [\"GET /marketplace_listing/stubbed/plans/{plan_id}/accounts\"],\n    listInstallationReposForAuthenticatedUser: [\"GET /user/installations/{installation_id}/repositories\"],\n    listInstallations: [\"GET /app/installations\"],\n    listInstallationsForAuthenticatedUser: [\"GET /user/installations\"],\n    listPlans: [\"GET /marketplace_listing/plans\"],\n    listPlansStubbed: [\"GET /marketplace_listing/stubbed/plans\"],\n    listReposAccessibleToInstallation: [\"GET /installation/repositories\"],\n    listSubscriptionsForAuthenticatedUser: [\"GET /user/marketplace_purchases\"],\n    listSubscriptionsForAuthenticatedUserStubbed: [\"GET /user/marketplace_purchases/stubbed\"],\n    removeRepoFromInstallation: [\"DELETE /user/installations/{installation_id}/repositories/{repository_id}\"],\n    resetToken: [\"PATCH /applications/{client_id}/token\"],\n    revokeInstallationAccessToken: [\"DELETE /installation/token\"],\n    scopeToken: [\"POST /applications/{client_id}/token/scoped\"],\n    suspendInstallation: [\"PUT /app/installations/{installation_id}/suspended\"],\n    unsuspendInstallation: [\"DELETE /app/installations/{installation_id}/suspended\"],\n    updateWebhookConfigForApp: [\"PATCH /app/hook/config\"]\n  },\n  billing: {\n    getGithubActionsBillingOrg: [\"GET /orgs/{org}/settings/billing/actions\"],\n    getGithubActionsBillingUser: [\"GET /users/{username}/settings/billing/actions\"],\n    getGithubPackagesBillingOrg: [\"GET /orgs/{org}/settings/billing/packages\"],\n    getGithubPackagesBillingUser: [\"GET /users/{username}/settings/billing/packages\"],\n    getSharedStorageBillingOrg: [\"GET /orgs/{org}/settings/billing/shared-storage\"],\n    getSharedStorageBillingUser: [\"GET /users/{username}/settings/billing/shared-storage\"]\n  },\n  checks: {\n    create: [\"POST /repos/{owner}/{repo}/check-runs\"],\n    createSuite: [\"POST /repos/{owner}/{repo}/check-suites\"],\n    get: [\"GET /repos/{owner}/{repo}/check-runs/{check_run_id}\"],\n    getSuite: [\"GET /repos/{owner}/{repo}/check-suites/{check_suite_id}\"],\n    listAnnotations: [\"GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations\"],\n    listForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/check-runs\"],\n    listForSuite: [\"GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs\"],\n    listSuitesForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/check-suites\"],\n    rerequestSuite: [\"POST /repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest\"],\n    setSuitesPreferences: [\"PATCH /repos/{owner}/{repo}/check-suites/preferences\"],\n    update: [\"PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}\"]\n  },\n  codeScanning: {\n    deleteAnalysis: [\"DELETE /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}{?confirm_delete}\"],\n    getAlert: [\"GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}\", {}, {\n      renamedParameters: {\n        alert_id: \"alert_number\"\n      }\n    }],\n    getAnalysis: [\"GET /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}\"],\n    getSarif: [\"GET /repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}\"],\n    listAlertsForRepo: [\"GET /repos/{owner}/{repo}/code-scanning/alerts\"],\n    listAlertsInstances: [\"GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances\"],\n    listRecentAnalyses: [\"GET /repos/{owner}/{repo}/code-scanning/analyses\"],\n    updateAlert: [\"PATCH /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}\"],\n    uploadSarif: [\"POST /repos/{owner}/{repo}/code-scanning/sarifs\"]\n  },\n  codesOfConduct: {\n    getAllCodesOfConduct: [\"GET /codes_of_conduct\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }],\n    getConductCode: [\"GET /codes_of_conduct/{key}\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }],\n    getForRepo: [\"GET /repos/{owner}/{repo}/community/code_of_conduct\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }]\n  },\n  emojis: {\n    get: [\"GET /emojis\"]\n  },\n  enterpriseAdmin: {\n    disableSelectedOrganizationGithubActionsEnterprise: [\"DELETE /enterprises/{enterprise}/actions/permissions/organizations/{org_id}\"],\n    enableSelectedOrganizationGithubActionsEnterprise: [\"PUT /enterprises/{enterprise}/actions/permissions/organizations/{org_id}\"],\n    getAllowedActionsEnterprise: [\"GET /enterprises/{enterprise}/actions/permissions/selected-actions\"],\n    getGithubActionsPermissionsEnterprise: [\"GET /enterprises/{enterprise}/actions/permissions\"],\n    listSelectedOrganizationsEnabledGithubActionsEnterprise: [\"GET /enterprises/{enterprise}/actions/permissions/organizations\"],\n    setAllowedActionsEnterprise: [\"PUT /enterprises/{enterprise}/actions/permissions/selected-actions\"],\n    setGithubActionsPermissionsEnterprise: [\"PUT /enterprises/{enterprise}/actions/permissions\"],\n    setSelectedOrganizationsEnabledGithubActionsEnterprise: [\"PUT /enterprises/{enterprise}/actions/permissions/organizations\"]\n  },\n  gists: {\n    checkIsStarred: [\"GET /gists/{gist_id}/star\"],\n    create: [\"POST /gists\"],\n    createComment: [\"POST /gists/{gist_id}/comments\"],\n    delete: [\"DELETE /gists/{gist_id}\"],\n    deleteComment: [\"DELETE /gists/{gist_id}/comments/{comment_id}\"],\n    fork: [\"POST /gists/{gist_id}/forks\"],\n    get: [\"GET /gists/{gist_id}\"],\n    getComment: [\"GET /gists/{gist_id}/comments/{comment_id}\"],\n    getRevision: [\"GET /gists/{gist_id}/{sha}\"],\n    list: [\"GET /gists\"],\n    listComments: [\"GET /gists/{gist_id}/comments\"],\n    listCommits: [\"GET /gists/{gist_id}/commits\"],\n    listForUser: [\"GET /users/{username}/gists\"],\n    listForks: [\"GET /gists/{gist_id}/forks\"],\n    listPublic: [\"GET /gists/public\"],\n    listStarred: [\"GET /gists/starred\"],\n    star: [\"PUT /gists/{gist_id}/star\"],\n    unstar: [\"DELETE /gists/{gist_id}/star\"],\n    update: [\"PATCH /gists/{gist_id}\"],\n    updateComment: [\"PATCH /gists/{gist_id}/comments/{comment_id}\"]\n  },\n  git: {\n    createBlob: [\"POST /repos/{owner}/{repo}/git/blobs\"],\n    createCommit: [\"POST /repos/{owner}/{repo}/git/commits\"],\n    createRef: [\"POST /repos/{owner}/{repo}/git/refs\"],\n    createTag: [\"POST /repos/{owner}/{repo}/git/tags\"],\n    createTree: [\"POST /repos/{owner}/{repo}/git/trees\"],\n    deleteRef: [\"DELETE /repos/{owner}/{repo}/git/refs/{ref}\"],\n    getBlob: [\"GET /repos/{owner}/{repo}/git/blobs/{file_sha}\"],\n    getCommit: [\"GET /repos/{owner}/{repo}/git/commits/{commit_sha}\"],\n    getRef: [\"GET /repos/{owner}/{repo}/git/ref/{ref}\"],\n    getTag: [\"GET /repos/{owner}/{repo}/git/tags/{tag_sha}\"],\n    getTree: [\"GET /repos/{owner}/{repo}/git/trees/{tree_sha}\"],\n    listMatchingRefs: [\"GET /repos/{owner}/{repo}/git/matching-refs/{ref}\"],\n    updateRef: [\"PATCH /repos/{owner}/{repo}/git/refs/{ref}\"]\n  },\n  gitignore: {\n    getAllTemplates: [\"GET /gitignore/templates\"],\n    getTemplate: [\"GET /gitignore/templates/{name}\"]\n  },\n  interactions: {\n    getRestrictionsForAuthenticatedUser: [\"GET /user/interaction-limits\"],\n    getRestrictionsForOrg: [\"GET /orgs/{org}/interaction-limits\"],\n    getRestrictionsForRepo: [\"GET /repos/{owner}/{repo}/interaction-limits\"],\n    getRestrictionsForYourPublicRepos: [\"GET /user/interaction-limits\", {}, {\n      renamed: [\"interactions\", \"getRestrictionsForAuthenticatedUser\"]\n    }],\n    removeRestrictionsForAuthenticatedUser: [\"DELETE /user/interaction-limits\"],\n    removeRestrictionsForOrg: [\"DELETE /orgs/{org}/interaction-limits\"],\n    removeRestrictionsForRepo: [\"DELETE /repos/{owner}/{repo}/interaction-limits\"],\n    removeRestrictionsForYourPublicRepos: [\"DELETE /user/interaction-limits\", {}, {\n      renamed: [\"interactions\", \"removeRestrictionsForAuthenticatedUser\"]\n    }],\n    setRestrictionsForAuthenticatedUser: [\"PUT /user/interaction-limits\"],\n    setRestrictionsForOrg: [\"PUT /orgs/{org}/interaction-limits\"],\n    setRestrictionsForRepo: [\"PUT /repos/{owner}/{repo}/interaction-limits\"],\n    setRestrictionsForYourPublicRepos: [\"PUT /user/interaction-limits\", {}, {\n      renamed: [\"interactions\", \"setRestrictionsForAuthenticatedUser\"]\n    }]\n  },\n  issues: {\n    addAssignees: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/assignees\"],\n    addLabels: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    checkUserCanBeAssigned: [\"GET /repos/{owner}/{repo}/assignees/{assignee}\"],\n    create: [\"POST /repos/{owner}/{repo}/issues\"],\n    createComment: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/comments\"],\n    createLabel: [\"POST /repos/{owner}/{repo}/labels\"],\n    createMilestone: [\"POST /repos/{owner}/{repo}/milestones\"],\n    deleteComment: [\"DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    deleteLabel: [\"DELETE /repos/{owner}/{repo}/labels/{name}\"],\n    deleteMilestone: [\"DELETE /repos/{owner}/{repo}/milestones/{milestone_number}\"],\n    get: [\"GET /repos/{owner}/{repo}/issues/{issue_number}\"],\n    getComment: [\"GET /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    getEvent: [\"GET /repos/{owner}/{repo}/issues/events/{event_id}\"],\n    getLabel: [\"GET /repos/{owner}/{repo}/labels/{name}\"],\n    getMilestone: [\"GET /repos/{owner}/{repo}/milestones/{milestone_number}\"],\n    list: [\"GET /issues\"],\n    listAssignees: [\"GET /repos/{owner}/{repo}/assignees\"],\n    listComments: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/comments\"],\n    listCommentsForRepo: [\"GET /repos/{owner}/{repo}/issues/comments\"],\n    listEvents: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/events\"],\n    listEventsForRepo: [\"GET /repos/{owner}/{repo}/issues/events\"],\n    listEventsForTimeline: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/timeline\", {\n      mediaType: {\n        previews: [\"mockingbird\"]\n      }\n    }],\n    listForAuthenticatedUser: [\"GET /user/issues\"],\n    listForOrg: [\"GET /orgs/{org}/issues\"],\n    listForRepo: [\"GET /repos/{owner}/{repo}/issues\"],\n    listLabelsForMilestone: [\"GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels\"],\n    listLabelsForRepo: [\"GET /repos/{owner}/{repo}/labels\"],\n    listLabelsOnIssue: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    listMilestones: [\"GET /repos/{owner}/{repo}/milestones\"],\n    lock: [\"PUT /repos/{owner}/{repo}/issues/{issue_number}/lock\"],\n    removeAllLabels: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    removeAssignees: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/assignees\"],\n    removeLabel: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}\"],\n    setLabels: [\"PUT /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    unlock: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/lock\"],\n    update: [\"PATCH /repos/{owner}/{repo}/issues/{issue_number}\"],\n    updateComment: [\"PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    updateLabel: [\"PATCH /repos/{owner}/{repo}/labels/{name}\"],\n    updateMilestone: [\"PATCH /repos/{owner}/{repo}/milestones/{milestone_number}\"]\n  },\n  licenses: {\n    get: [\"GET /licenses/{license}\"],\n    getAllCommonlyUsed: [\"GET /licenses\"],\n    getForRepo: [\"GET /repos/{owner}/{repo}/license\"]\n  },\n  markdown: {\n    render: [\"POST /markdown\"],\n    renderRaw: [\"POST /markdown/raw\", {\n      headers: {\n        \"content-type\": \"text/plain; charset=utf-8\"\n      }\n    }]\n  },\n  meta: {\n    get: [\"GET /meta\"],\n    getOctocat: [\"GET /octocat\"],\n    getZen: [\"GET /zen\"],\n    root: [\"GET /\"]\n  },\n  migrations: {\n    cancelImport: [\"DELETE /repos/{owner}/{repo}/import\"],\n    deleteArchiveForAuthenticatedUser: [\"DELETE /user/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    deleteArchiveForOrg: [\"DELETE /orgs/{org}/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    downloadArchiveForOrg: [\"GET /orgs/{org}/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getArchiveForAuthenticatedUser: [\"GET /user/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getCommitAuthors: [\"GET /repos/{owner}/{repo}/import/authors\"],\n    getImportStatus: [\"GET /repos/{owner}/{repo}/import\"],\n    getLargeFiles: [\"GET /repos/{owner}/{repo}/import/large_files\"],\n    getStatusForAuthenticatedUser: [\"GET /user/migrations/{migration_id}\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getStatusForOrg: [\"GET /orgs/{org}/migrations/{migration_id}\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listForAuthenticatedUser: [\"GET /user/migrations\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listForOrg: [\"GET /orgs/{org}/migrations\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listReposForOrg: [\"GET /orgs/{org}/migrations/{migration_id}/repositories\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listReposForUser: [\"GET /user/migrations/{migration_id}/repositories\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    mapCommitAuthor: [\"PATCH /repos/{owner}/{repo}/import/authors/{author_id}\"],\n    setLfsPreference: [\"PATCH /repos/{owner}/{repo}/import/lfs\"],\n    startForAuthenticatedUser: [\"POST /user/migrations\"],\n    startForOrg: [\"POST /orgs/{org}/migrations\"],\n    startImport: [\"PUT /repos/{owner}/{repo}/import\"],\n    unlockRepoForAuthenticatedUser: [\"DELETE /user/migrations/{migration_id}/repos/{repo_name}/lock\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    unlockRepoForOrg: [\"DELETE /orgs/{org}/migrations/{migration_id}/repos/{repo_name}/lock\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    updateImport: [\"PATCH /repos/{owner}/{repo}/import\"]\n  },\n  orgs: {\n    blockUser: [\"PUT /orgs/{org}/blocks/{username}\"],\n    cancelInvitation: [\"DELETE /orgs/{org}/invitations/{invitation_id}\"],\n    checkBlockedUser: [\"GET /orgs/{org}/blocks/{username}\"],\n    checkMembershipForUser: [\"GET /orgs/{org}/members/{username}\"],\n    checkPublicMembershipForUser: [\"GET /orgs/{org}/public_members/{username}\"],\n    convertMemberToOutsideCollaborator: [\"PUT /orgs/{org}/outside_collaborators/{username}\"],\n    createInvitation: [\"POST /orgs/{org}/invitations\"],\n    createWebhook: [\"POST /orgs/{org}/hooks\"],\n    deleteWebhook: [\"DELETE /orgs/{org}/hooks/{hook_id}\"],\n    get: [\"GET /orgs/{org}\"],\n    getMembershipForAuthenticatedUser: [\"GET /user/memberships/orgs/{org}\"],\n    getMembershipForUser: [\"GET /orgs/{org}/memberships/{username}\"],\n    getWebhook: [\"GET /orgs/{org}/hooks/{hook_id}\"],\n    getWebhookConfigForOrg: [\"GET /orgs/{org}/hooks/{hook_id}/config\"],\n    list: [\"GET /organizations\"],\n    listAppInstallations: [\"GET /orgs/{org}/installations\"],\n    listBlockedUsers: [\"GET /orgs/{org}/blocks\"],\n    listFailedInvitations: [\"GET /orgs/{org}/failed_invitations\"],\n    listForAuthenticatedUser: [\"GET /user/orgs\"],\n    listForUser: [\"GET /users/{username}/orgs\"],\n    listInvitationTeams: [\"GET /orgs/{org}/invitations/{invitation_id}/teams\"],\n    listMembers: [\"GET /orgs/{org}/members\"],\n    listMembershipsForAuthenticatedUser: [\"GET /user/memberships/orgs\"],\n    listOutsideCollaborators: [\"GET /orgs/{org}/outside_collaborators\"],\n    listPendingInvitations: [\"GET /orgs/{org}/invitations\"],\n    listPublicMembers: [\"GET /orgs/{org}/public_members\"],\n    listWebhooks: [\"GET /orgs/{org}/hooks\"],\n    pingWebhook: [\"POST /orgs/{org}/hooks/{hook_id}/pings\"],\n    removeMember: [\"DELETE /orgs/{org}/members/{username}\"],\n    removeMembershipForUser: [\"DELETE /orgs/{org}/memberships/{username}\"],\n    removeOutsideCollaborator: [\"DELETE /orgs/{org}/outside_collaborators/{username}\"],\n    removePublicMembershipForAuthenticatedUser: [\"DELETE /orgs/{org}/public_members/{username}\"],\n    setMembershipForUser: [\"PUT /orgs/{org}/memberships/{username}\"],\n    setPublicMembershipForAuthenticatedUser: [\"PUT /orgs/{org}/public_members/{username}\"],\n    unblockUser: [\"DELETE /orgs/{org}/blocks/{username}\"],\n    update: [\"PATCH /orgs/{org}\"],\n    updateMembershipForAuthenticatedUser: [\"PATCH /user/memberships/orgs/{org}\"],\n    updateWebhook: [\"PATCH /orgs/{org}/hooks/{hook_id}\"],\n    updateWebhookConfigForOrg: [\"PATCH /orgs/{org}/hooks/{hook_id}/config\"]\n  },\n  packages: {\n    deletePackageForAuthenticatedUser: [\"DELETE /user/packages/{package_type}/{package_name}\"],\n    deletePackageForOrg: [\"DELETE /orgs/{org}/packages/{package_type}/{package_name}\"],\n    deletePackageVersionForAuthenticatedUser: [\"DELETE /user/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    deletePackageVersionForOrg: [\"DELETE /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    getAllPackageVersionsForAPackageOwnedByAnOrg: [\"GET /orgs/{org}/packages/{package_type}/{package_name}/versions\", {}, {\n      renamed: [\"packages\", \"getAllPackageVersionsForPackageOwnedByOrg\"]\n    }],\n    getAllPackageVersionsForAPackageOwnedByTheAuthenticatedUser: [\"GET /user/packages/{package_type}/{package_name}/versions\", {}, {\n      renamed: [\"packages\", \"getAllPackageVersionsForPackageOwnedByAuthenticatedUser\"]\n    }],\n    getAllPackageVersionsForPackageOwnedByAuthenticatedUser: [\"GET /user/packages/{package_type}/{package_name}/versions\"],\n    getAllPackageVersionsForPackageOwnedByOrg: [\"GET /orgs/{org}/packages/{package_type}/{package_name}/versions\"],\n    getAllPackageVersionsForPackageOwnedByUser: [\"GET /users/{username}/packages/{package_type}/{package_name}/versions\"],\n    getPackageForAuthenticatedUser: [\"GET /user/packages/{package_type}/{package_name}\"],\n    getPackageForOrganization: [\"GET /orgs/{org}/packages/{package_type}/{package_name}\"],\n    getPackageForUser: [\"GET /users/{username}/packages/{package_type}/{package_name}\"],\n    getPackageVersionForAuthenticatedUser: [\"GET /user/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    getPackageVersionForOrganization: [\"GET /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    getPackageVersionForUser: [\"GET /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    restorePackageForAuthenticatedUser: [\"POST /user/packages/{package_type}/{package_name}/restore{?token}\"],\n    restorePackageForOrg: [\"POST /orgs/{org}/packages/{package_type}/{package_name}/restore{?token}\"],\n    restorePackageVersionForAuthenticatedUser: [\"POST /user/packages/{package_type}/{package_name}/versions/{package_version_id}/restore\"],\n    restorePackageVersionForOrg: [\"POST /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore\"]\n  },\n  projects: {\n    addCollaborator: [\"PUT /projects/{project_id}/collaborators/{username}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createCard: [\"POST /projects/columns/{column_id}/cards\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createColumn: [\"POST /projects/{project_id}/columns\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForAuthenticatedUser: [\"POST /user/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForOrg: [\"POST /orgs/{org}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForRepo: [\"POST /repos/{owner}/{repo}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    delete: [\"DELETE /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    deleteCard: [\"DELETE /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    deleteColumn: [\"DELETE /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    get: [\"GET /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getCard: [\"GET /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getColumn: [\"GET /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getPermissionForUser: [\"GET /projects/{project_id}/collaborators/{username}/permission\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listCards: [\"GET /projects/columns/{column_id}/cards\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listCollaborators: [\"GET /projects/{project_id}/collaborators\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listColumns: [\"GET /projects/{project_id}/columns\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForOrg: [\"GET /orgs/{org}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForRepo: [\"GET /repos/{owner}/{repo}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForUser: [\"GET /users/{username}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    moveCard: [\"POST /projects/columns/cards/{card_id}/moves\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    moveColumn: [\"POST /projects/columns/{column_id}/moves\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    removeCollaborator: [\"DELETE /projects/{project_id}/collaborators/{username}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    update: [\"PATCH /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    updateCard: [\"PATCH /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    updateColumn: [\"PATCH /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }]\n  },\n  pulls: {\n    checkIfMerged: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/merge\"],\n    create: [\"POST /repos/{owner}/{repo}/pulls\"],\n    createReplyForReviewComment: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies\"],\n    createReview: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews\"],\n    createReviewComment: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/comments\"],\n    deletePendingReview: [\"DELETE /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    deleteReviewComment: [\"DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}\"],\n    dismissReview: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals\"],\n    get: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}\"],\n    getReview: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    getReviewComment: [\"GET /repos/{owner}/{repo}/pulls/comments/{comment_id}\"],\n    list: [\"GET /repos/{owner}/{repo}/pulls\"],\n    listCommentsForReview: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments\"],\n    listCommits: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/commits\"],\n    listFiles: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\"],\n    listRequestedReviewers: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    listReviewComments: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/comments\"],\n    listReviewCommentsForRepo: [\"GET /repos/{owner}/{repo}/pulls/comments\"],\n    listReviews: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews\"],\n    merge: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge\"],\n    removeRequestedReviewers: [\"DELETE /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    requestReviewers: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    submitReview: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/events\"],\n    update: [\"PATCH /repos/{owner}/{repo}/pulls/{pull_number}\"],\n    updateBranch: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch\", {\n      mediaType: {\n        previews: [\"lydian\"]\n      }\n    }],\n    updateReview: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    updateReviewComment: [\"PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}\"]\n  },\n  rateLimit: {\n    get: [\"GET /rate_limit\"]\n  },\n  reactions: {\n    createForCommitComment: [\"POST /repos/{owner}/{repo}/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForIssue: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForIssueComment: [\"POST /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForPullRequestReviewComment: [\"POST /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForTeamDiscussionCommentInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForTeamDiscussionInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForCommitComment: [\"DELETE /repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForIssue: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForIssueComment: [\"DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForPullRequestComment: [\"DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForTeamDiscussion: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForTeamDiscussionComment: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteLegacy: [\"DELETE /reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }, {\n      deprecated: \"octokit.rest.reactions.deleteLegacy() is deprecated, see https://docs.github.com/rest/reference/reactions/#delete-a-reaction-legacy\"\n    }],\n    listForCommitComment: [\"GET /repos/{owner}/{repo}/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForIssue: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForIssueComment: [\"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForPullRequestReviewComment: [\"GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForTeamDiscussionCommentInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForTeamDiscussionInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }]\n  },\n  repos: {\n    acceptInvitation: [\"PATCH /user/repository_invitations/{invitation_id}\"],\n    addAppAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    addCollaborator: [\"PUT /repos/{owner}/{repo}/collaborators/{username}\"],\n    addStatusCheckContexts: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    addTeamAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    addUserAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    checkCollaborator: [\"GET /repos/{owner}/{repo}/collaborators/{username}\"],\n    checkVulnerabilityAlerts: [\"GET /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    compareCommits: [\"GET /repos/{owner}/{repo}/compare/{base}...{head}\"],\n    createCommitComment: [\"POST /repos/{owner}/{repo}/commits/{commit_sha}/comments\"],\n    createCommitSignatureProtection: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    createCommitStatus: [\"POST /repos/{owner}/{repo}/statuses/{sha}\"],\n    createDeployKey: [\"POST /repos/{owner}/{repo}/keys\"],\n    createDeployment: [\"POST /repos/{owner}/{repo}/deployments\"],\n    createDeploymentStatus: [\"POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses\"],\n    createDispatchEvent: [\"POST /repos/{owner}/{repo}/dispatches\"],\n    createForAuthenticatedUser: [\"POST /user/repos\"],\n    createFork: [\"POST /repos/{owner}/{repo}/forks\"],\n    createInOrg: [\"POST /orgs/{org}/repos\"],\n    createOrUpdateEnvironment: [\"PUT /repos/{owner}/{repo}/environments/{environment_name}\"],\n    createOrUpdateFileContents: [\"PUT /repos/{owner}/{repo}/contents/{path}\"],\n    createPagesSite: [\"POST /repos/{owner}/{repo}/pages\", {\n      mediaType: {\n        previews: [\"switcheroo\"]\n      }\n    }],\n    createRelease: [\"POST /repos/{owner}/{repo}/releases\"],\n    createUsingTemplate: [\"POST /repos/{template_owner}/{template_repo}/generate\", {\n      mediaType: {\n        previews: [\"baptiste\"]\n      }\n    }],\n    createWebhook: [\"POST /repos/{owner}/{repo}/hooks\"],\n    declineInvitation: [\"DELETE /user/repository_invitations/{invitation_id}\"],\n    delete: [\"DELETE /repos/{owner}/{repo}\"],\n    deleteAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions\"],\n    deleteAdminBranchProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    deleteAnEnvironment: [\"DELETE /repos/{owner}/{repo}/environments/{environment_name}\"],\n    deleteBranchProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    deleteCommitComment: [\"DELETE /repos/{owner}/{repo}/comments/{comment_id}\"],\n    deleteCommitSignatureProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    deleteDeployKey: [\"DELETE /repos/{owner}/{repo}/keys/{key_id}\"],\n    deleteDeployment: [\"DELETE /repos/{owner}/{repo}/deployments/{deployment_id}\"],\n    deleteFile: [\"DELETE /repos/{owner}/{repo}/contents/{path}\"],\n    deleteInvitation: [\"DELETE /repos/{owner}/{repo}/invitations/{invitation_id}\"],\n    deletePagesSite: [\"DELETE /repos/{owner}/{repo}/pages\", {\n      mediaType: {\n        previews: [\"switcheroo\"]\n      }\n    }],\n    deletePullRequestReviewProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    deleteRelease: [\"DELETE /repos/{owner}/{repo}/releases/{release_id}\"],\n    deleteReleaseAsset: [\"DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    deleteWebhook: [\"DELETE /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    disableAutomatedSecurityFixes: [\"DELETE /repos/{owner}/{repo}/automated-security-fixes\", {\n      mediaType: {\n        previews: [\"london\"]\n      }\n    }],\n    disableVulnerabilityAlerts: [\"DELETE /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    downloadArchive: [\"GET /repos/{owner}/{repo}/zipball/{ref}\", {}, {\n      renamed: [\"repos\", \"downloadZipballArchive\"]\n    }],\n    downloadTarballArchive: [\"GET /repos/{owner}/{repo}/tarball/{ref}\"],\n    downloadZipballArchive: [\"GET /repos/{owner}/{repo}/zipball/{ref}\"],\n    enableAutomatedSecurityFixes: [\"PUT /repos/{owner}/{repo}/automated-security-fixes\", {\n      mediaType: {\n        previews: [\"london\"]\n      }\n    }],\n    enableVulnerabilityAlerts: [\"PUT /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    get: [\"GET /repos/{owner}/{repo}\"],\n    getAccessRestrictions: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions\"],\n    getAdminBranchProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    getAllEnvironments: [\"GET /repos/{owner}/{repo}/environments\"],\n    getAllStatusCheckContexts: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\"],\n    getAllTopics: [\"GET /repos/{owner}/{repo}/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    getAppsWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\"],\n    getBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}\"],\n    getBranchProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    getClones: [\"GET /repos/{owner}/{repo}/traffic/clones\"],\n    getCodeFrequencyStats: [\"GET /repos/{owner}/{repo}/stats/code_frequency\"],\n    getCollaboratorPermissionLevel: [\"GET /repos/{owner}/{repo}/collaborators/{username}/permission\"],\n    getCombinedStatusForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/status\"],\n    getCommit: [\"GET /repos/{owner}/{repo}/commits/{ref}\"],\n    getCommitActivityStats: [\"GET /repos/{owner}/{repo}/stats/commit_activity\"],\n    getCommitComment: [\"GET /repos/{owner}/{repo}/comments/{comment_id}\"],\n    getCommitSignatureProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    getCommunityProfileMetrics: [\"GET /repos/{owner}/{repo}/community/profile\"],\n    getContent: [\"GET /repos/{owner}/{repo}/contents/{path}\"],\n    getContributorsStats: [\"GET /repos/{owner}/{repo}/stats/contributors\"],\n    getDeployKey: [\"GET /repos/{owner}/{repo}/keys/{key_id}\"],\n    getDeployment: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}\"],\n    getDeploymentStatus: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}\"],\n    getEnvironment: [\"GET /repos/{owner}/{repo}/environments/{environment_name}\"],\n    getLatestPagesBuild: [\"GET /repos/{owner}/{repo}/pages/builds/latest\"],\n    getLatestRelease: [\"GET /repos/{owner}/{repo}/releases/latest\"],\n    getPages: [\"GET /repos/{owner}/{repo}/pages\"],\n    getPagesBuild: [\"GET /repos/{owner}/{repo}/pages/builds/{build_id}\"],\n    getParticipationStats: [\"GET /repos/{owner}/{repo}/stats/participation\"],\n    getPullRequestReviewProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    getPunchCardStats: [\"GET /repos/{owner}/{repo}/stats/punch_card\"],\n    getReadme: [\"GET /repos/{owner}/{repo}/readme\"],\n    getReadmeInDirectory: [\"GET /repos/{owner}/{repo}/readme/{dir}\"],\n    getRelease: [\"GET /repos/{owner}/{repo}/releases/{release_id}\"],\n    getReleaseAsset: [\"GET /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    getReleaseByTag: [\"GET /repos/{owner}/{repo}/releases/tags/{tag}\"],\n    getStatusChecksProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    getTeamsWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\"],\n    getTopPaths: [\"GET /repos/{owner}/{repo}/traffic/popular/paths\"],\n    getTopReferrers: [\"GET /repos/{owner}/{repo}/traffic/popular/referrers\"],\n    getUsersWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\"],\n    getViews: [\"GET /repos/{owner}/{repo}/traffic/views\"],\n    getWebhook: [\"GET /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    getWebhookConfigForRepo: [\"GET /repos/{owner}/{repo}/hooks/{hook_id}/config\"],\n    listBranches: [\"GET /repos/{owner}/{repo}/branches\"],\n    listBranchesForHeadCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head\", {\n      mediaType: {\n        previews: [\"groot\"]\n      }\n    }],\n    listCollaborators: [\"GET /repos/{owner}/{repo}/collaborators\"],\n    listCommentsForCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/comments\"],\n    listCommitCommentsForRepo: [\"GET /repos/{owner}/{repo}/comments\"],\n    listCommitStatusesForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/statuses\"],\n    listCommits: [\"GET /repos/{owner}/{repo}/commits\"],\n    listContributors: [\"GET /repos/{owner}/{repo}/contributors\"],\n    listDeployKeys: [\"GET /repos/{owner}/{repo}/keys\"],\n    listDeploymentStatuses: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses\"],\n    listDeployments: [\"GET /repos/{owner}/{repo}/deployments\"],\n    listForAuthenticatedUser: [\"GET /user/repos\"],\n    listForOrg: [\"GET /orgs/{org}/repos\"],\n    listForUser: [\"GET /users/{username}/repos\"],\n    listForks: [\"GET /repos/{owner}/{repo}/forks\"],\n    listInvitations: [\"GET /repos/{owner}/{repo}/invitations\"],\n    listInvitationsForAuthenticatedUser: [\"GET /user/repository_invitations\"],\n    listLanguages: [\"GET /repos/{owner}/{repo}/languages\"],\n    listPagesBuilds: [\"GET /repos/{owner}/{repo}/pages/builds\"],\n    listPublic: [\"GET /repositories\"],\n    listPullRequestsAssociatedWithCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls\", {\n      mediaType: {\n        previews: [\"groot\"]\n      }\n    }],\n    listReleaseAssets: [\"GET /repos/{owner}/{repo}/releases/{release_id}/assets\"],\n    listReleases: [\"GET /repos/{owner}/{repo}/releases\"],\n    listTags: [\"GET /repos/{owner}/{repo}/tags\"],\n    listTeams: [\"GET /repos/{owner}/{repo}/teams\"],\n    listWebhooks: [\"GET /repos/{owner}/{repo}/hooks\"],\n    merge: [\"POST /repos/{owner}/{repo}/merges\"],\n    pingWebhook: [\"POST /repos/{owner}/{repo}/hooks/{hook_id}/pings\"],\n    removeAppAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    removeCollaborator: [\"DELETE /repos/{owner}/{repo}/collaborators/{username}\"],\n    removeStatusCheckContexts: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    removeStatusCheckProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    removeTeamAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    removeUserAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    renameBranch: [\"POST /repos/{owner}/{repo}/branches/{branch}/rename\"],\n    replaceAllTopics: [\"PUT /repos/{owner}/{repo}/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    requestPagesBuild: [\"POST /repos/{owner}/{repo}/pages/builds\"],\n    setAdminBranchProtection: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    setAppAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    setStatusCheckContexts: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    setTeamAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    setUserAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    testPushWebhook: [\"POST /repos/{owner}/{repo}/hooks/{hook_id}/tests\"],\n    transfer: [\"POST /repos/{owner}/{repo}/transfer\"],\n    update: [\"PATCH /repos/{owner}/{repo}\"],\n    updateBranchProtection: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    updateCommitComment: [\"PATCH /repos/{owner}/{repo}/comments/{comment_id}\"],\n    updateInformationAboutPagesSite: [\"PUT /repos/{owner}/{repo}/pages\"],\n    updateInvitation: [\"PATCH /repos/{owner}/{repo}/invitations/{invitation_id}\"],\n    updatePullRequestReviewProtection: [\"PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    updateRelease: [\"PATCH /repos/{owner}/{repo}/releases/{release_id}\"],\n    updateReleaseAsset: [\"PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    updateStatusCheckPotection: [\"PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\", {}, {\n      renamed: [\"repos\", \"updateStatusCheckProtection\"]\n    }],\n    updateStatusCheckProtection: [\"PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    updateWebhook: [\"PATCH /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    updateWebhookConfigForRepo: [\"PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config\"],\n    uploadReleaseAsset: [\"POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}\", {\n      baseUrl: \"https://uploads.github.com\"\n    }]\n  },\n  search: {\n    code: [\"GET /search/code\"],\n    commits: [\"GET /search/commits\", {\n      mediaType: {\n        previews: [\"cloak\"]\n      }\n    }],\n    issuesAndPullRequests: [\"GET /search/issues\"],\n    labels: [\"GET /search/labels\"],\n    repos: [\"GET /search/repositories\"],\n    topics: [\"GET /search/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    users: [\"GET /search/users\"]\n  },\n  secretScanning: {\n    getAlert: [\"GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}\"],\n    listAlertsForRepo: [\"GET /repos/{owner}/{repo}/secret-scanning/alerts\"],\n    updateAlert: [\"PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}\"]\n  },\n  teams: {\n    addOrUpdateMembershipForUserInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    addOrUpdateProjectPermissionsInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    addOrUpdateRepoPermissionsInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    checkPermissionsForProjectInOrg: [\"GET /orgs/{org}/teams/{team_slug}/projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    checkPermissionsForRepoInOrg: [\"GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    create: [\"POST /orgs/{org}/teams\"],\n    createDiscussionCommentInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments\"],\n    createDiscussionInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions\"],\n    deleteDiscussionCommentInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    deleteDiscussionInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    deleteInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}\"],\n    getByName: [\"GET /orgs/{org}/teams/{team_slug}\"],\n    getDiscussionCommentInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    getDiscussionInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    getMembershipForUserInOrg: [\"GET /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    list: [\"GET /orgs/{org}/teams\"],\n    listChildInOrg: [\"GET /orgs/{org}/teams/{team_slug}/teams\"],\n    listDiscussionCommentsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments\"],\n    listDiscussionsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions\"],\n    listForAuthenticatedUser: [\"GET /user/teams\"],\n    listMembersInOrg: [\"GET /orgs/{org}/teams/{team_slug}/members\"],\n    listPendingInvitationsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/invitations\"],\n    listProjectsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listReposInOrg: [\"GET /orgs/{org}/teams/{team_slug}/repos\"],\n    removeMembershipForUserInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    removeProjectInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}\"],\n    removeRepoInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    updateDiscussionCommentInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    updateDiscussionInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    updateInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}\"]\n  },\n  users: {\n    addEmailForAuthenticated: [\"POST /user/emails\"],\n    block: [\"PUT /user/blocks/{username}\"],\n    checkBlocked: [\"GET /user/blocks/{username}\"],\n    checkFollowingForUser: [\"GET /users/{username}/following/{target_user}\"],\n    checkPersonIsFollowedByAuthenticated: [\"GET /user/following/{username}\"],\n    createGpgKeyForAuthenticated: [\"POST /user/gpg_keys\"],\n    createPublicSshKeyForAuthenticated: [\"POST /user/keys\"],\n    deleteEmailForAuthenticated: [\"DELETE /user/emails\"],\n    deleteGpgKeyForAuthenticated: [\"DELETE /user/gpg_keys/{gpg_key_id}\"],\n    deletePublicSshKeyForAuthenticated: [\"DELETE /user/keys/{key_id}\"],\n    follow: [\"PUT /user/following/{username}\"],\n    getAuthenticated: [\"GET /user\"],\n    getByUsername: [\"GET /users/{username}\"],\n    getContextForUser: [\"GET /users/{username}/hovercard\"],\n    getGpgKeyForAuthenticated: [\"GET /user/gpg_keys/{gpg_key_id}\"],\n    getPublicSshKeyForAuthenticated: [\"GET /user/keys/{key_id}\"],\n    list: [\"GET /users\"],\n    listBlockedByAuthenticated: [\"GET /user/blocks\"],\n    listEmailsForAuthenticated: [\"GET /user/emails\"],\n    listFollowedByAuthenticated: [\"GET /user/following\"],\n    listFollowersForAuthenticatedUser: [\"GET /user/followers\"],\n    listFollowersForUser: [\"GET /users/{username}/followers\"],\n    listFollowingForUser: [\"GET /users/{username}/following\"],\n    listGpgKeysForAuthenticated: [\"GET /user/gpg_keys\"],\n    listGpgKeysForUser: [\"GET /users/{username}/gpg_keys\"],\n    listPublicEmailsForAuthenticated: [\"GET /user/public_emails\"],\n    listPublicKeysForUser: [\"GET /users/{username}/keys\"],\n    listPublicSshKeysForAuthenticated: [\"GET /user/keys\"],\n    setPrimaryEmailVisibilityForAuthenticated: [\"PATCH /user/email/visibility\"],\n    unblock: [\"DELETE /user/blocks/{username}\"],\n    unfollow: [\"DELETE /user/following/{username}\"],\n    updateAuthenticated: [\"PATCH /user\"]\n  }\n};\n\nconst VERSION = \"4.15.1\";\n\nfunction endpointsToMethods(octokit, endpointsMap) {\n  const newMethods = {};\n\n  for (const [scope, endpoints] of Object.entries(endpointsMap)) {\n    for (const [methodName, endpoint] of Object.entries(endpoints)) {\n      const [route, defaults, decorations] = endpoint;\n      const [method, url] = route.split(/ /);\n      const endpointDefaults = Object.assign({\n        method,\n        url\n      }, defaults);\n\n      if (!newMethods[scope]) {\n        newMethods[scope] = {};\n      }\n\n      const scopeMethods = newMethods[scope];\n\n      if (decorations) {\n        scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations);\n        continue;\n      }\n\n      scopeMethods[methodName] = octokit.request.defaults(endpointDefaults);\n    }\n  }\n\n  return newMethods;\n}\n\nfunction decorate(octokit, scope, methodName, defaults, decorations) {\n  const requestWithDefaults = octokit.request.defaults(defaults);\n  /* istanbul ignore next */\n\n  function withDecorations(...args) {\n    // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n    let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData`\n\n    if (decorations.mapToData) {\n      options = Object.assign({}, options, {\n        data: options[decorations.mapToData],\n        [decorations.mapToData]: undefined\n      });\n      return requestWithDefaults(options);\n    }\n\n    if (decorations.renamed) {\n      const [newScope, newMethodName] = decorations.renamed;\n      octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`);\n    }\n\n    if (decorations.deprecated) {\n      octokit.log.warn(decorations.deprecated);\n    }\n\n    if (decorations.renamedParameters) {\n      // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n      const options = requestWithDefaults.endpoint.merge(...args);\n\n      for (const [name, alias] of Object.entries(decorations.renamedParameters)) {\n        if (name in options) {\n          octokit.log.warn(`\"${name}\" parameter is deprecated for \"octokit.${scope}.${methodName}()\". Use \"${alias}\" instead`);\n\n          if (!(alias in options)) {\n            options[alias] = options[name];\n          }\n\n          delete options[name];\n        }\n      }\n\n      return requestWithDefaults(options);\n    } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n\n\n    return requestWithDefaults(...args);\n  }\n\n  return Object.assign(withDecorations, requestWithDefaults);\n}\n\nfunction restEndpointMethods(octokit) {\n  const api = endpointsToMethods(octokit, Endpoints);\n  return _objectSpread2(_objectSpread2({}, api), {}, {\n    rest: api\n  });\n}\nrestEndpointMethods.VERSION = VERSION;\n\nexports.restEndpointMethods = restEndpointMethods;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 537:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar deprecation = __webpack_require__(8932);\nvar once = _interopDefault(__webpack_require__(1223));\n\nconst logOnceCode = once(deprecation => console.warn(deprecation));\nconst logOnceHeaders = once(deprecation => console.warn(deprecation));\n/**\n * Error with extra properties to help with debugging\n */\n\nclass RequestError extends Error {\n  constructor(message, statusCode, options) {\n    super(message); // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n\n    this.name = \"HttpError\";\n    this.status = statusCode;\n    let headers;\n\n    if (\"headers\" in options && typeof options.headers !== \"undefined\") {\n      headers = options.headers;\n    }\n\n    if (\"response\" in options) {\n      this.response = options.response;\n      headers = options.response.headers;\n    } // redact request credentials without mutating original request options\n\n\n    const requestCopy = Object.assign({}, options.request);\n\n    if (options.request.headers.authorization) {\n      requestCopy.headers = Object.assign({}, options.request.headers, {\n        authorization: options.request.headers.authorization.replace(/ .*$/, \" [REDACTED]\")\n      });\n    }\n\n    requestCopy.url = requestCopy.url // client_id & client_secret can be passed as URL query parameters to increase rate limit\n    // see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications\n    .replace(/\\bclient_secret=\\w+/g, \"client_secret=[REDACTED]\") // OAuth tokens can be passed as URL query parameters, although it is not recommended\n    // see https://developer.github.com/v3/#oauth2-token-sent-in-a-header\n    .replace(/\\baccess_token=\\w+/g, \"access_token=[REDACTED]\");\n    this.request = requestCopy; // deprecations\n\n    Object.defineProperty(this, \"code\", {\n      get() {\n        logOnceCode(new deprecation.Deprecation(\"[@octokit/request-error] `error.code` is deprecated, use `error.status`.\"));\n        return statusCode;\n      }\n\n    });\n    Object.defineProperty(this, \"headers\", {\n      get() {\n        logOnceHeaders(new deprecation.Deprecation(\"[@octokit/request-error] `error.headers` is deprecated, use `error.response.headers`.\"));\n        return headers || {};\n      }\n\n    });\n  }\n\n}\n\nexports.RequestError = RequestError;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 6234:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar endpoint = __webpack_require__(9440);\nvar universalUserAgent = __webpack_require__(5030);\nvar isPlainObject = __webpack_require__(3287);\nvar nodeFetch = _interopDefault(__webpack_require__(467));\nvar requestError = __webpack_require__(537);\n\nconst VERSION = \"5.6.2\";\n\nfunction getBufferResponse(response) {\n  return response.arrayBuffer();\n}\n\nfunction fetchWrapper(requestOptions) {\n  const log = requestOptions.request && requestOptions.request.log ? requestOptions.request.log : console;\n\n  if (isPlainObject.isPlainObject(requestOptions.body) || Array.isArray(requestOptions.body)) {\n    requestOptions.body = JSON.stringify(requestOptions.body);\n  }\n\n  let headers = {};\n  let status;\n  let url;\n  const fetch = requestOptions.request && requestOptions.request.fetch || nodeFetch;\n  return fetch(requestOptions.url, Object.assign({\n    method: requestOptions.method,\n    body: requestOptions.body,\n    headers: requestOptions.headers,\n    redirect: requestOptions.redirect\n  }, // `requestOptions.request.agent` type is incompatible\n  // see https://github.com/octokit/types.ts/pull/264\n  requestOptions.request)).then(async response => {\n    url = response.url;\n    status = response.status;\n\n    for (const keyAndValue of response.headers) {\n      headers[keyAndValue[0]] = keyAndValue[1];\n    }\n\n    if (\"deprecation\" in headers) {\n      const matches = headers.link && headers.link.match(/<([^>]+)>; rel=\"deprecation\"/);\n      const deprecationLink = matches && matches.pop();\n      log.warn(`[@octokit/request] \"${requestOptions.method} ${requestOptions.url}\" is deprecated. It is scheduled to be removed on ${headers.sunset}${deprecationLink ? `. See ${deprecationLink}` : \"\"}`);\n    }\n\n    if (status === 204 || status === 205) {\n      return;\n    } // GitHub API returns 200 for HEAD requests\n\n\n    if (requestOptions.method === \"HEAD\") {\n      if (status < 400) {\n        return;\n      }\n\n      throw new requestError.RequestError(response.statusText, status, {\n        response: {\n          url,\n          status,\n          headers,\n          data: undefined\n        },\n        request: requestOptions\n      });\n    }\n\n    if (status === 304) {\n      throw new requestError.RequestError(\"Not modified\", status, {\n        response: {\n          url,\n          status,\n          headers,\n          data: await getResponseData(response)\n        },\n        request: requestOptions\n      });\n    }\n\n    if (status >= 400) {\n      const data = await getResponseData(response);\n      const error = new requestError.RequestError(toErrorMessage(data), status, {\n        response: {\n          url,\n          status,\n          headers,\n          data\n        },\n        request: requestOptions\n      });\n      throw error;\n    }\n\n    return getResponseData(response);\n  }).then(data => {\n    return {\n      status,\n      url,\n      headers,\n      data\n    };\n  }).catch(error => {\n    if (error instanceof requestError.RequestError) throw error;\n    throw new requestError.RequestError(error.message, 500, {\n      request: requestOptions\n    });\n  });\n}\n\nasync function getResponseData(response) {\n  const contentType = response.headers.get(\"content-type\");\n\n  if (/application\\/json/.test(contentType)) {\n    return response.json();\n  }\n\n  if (!contentType || /^text\\/|charset=utf-8$/.test(contentType)) {\n    return response.text();\n  }\n\n  return getBufferResponse(response);\n}\n\nfunction toErrorMessage(data) {\n  if (typeof data === \"string\") return data; // istanbul ignore else - just in case\n\n  if (\"message\" in data) {\n    if (Array.isArray(data.errors)) {\n      return `${data.message}: ${data.errors.map(JSON.stringify).join(\", \")}`;\n    }\n\n    return data.message;\n  } // istanbul ignore next - just in case\n\n\n  return `Unknown error: ${JSON.stringify(data)}`;\n}\n\nfunction withDefaults(oldEndpoint, newDefaults) {\n  const endpoint = oldEndpoint.defaults(newDefaults);\n\n  const newApi = function (route, parameters) {\n    const endpointOptions = endpoint.merge(route, parameters);\n\n    if (!endpointOptions.request || !endpointOptions.request.hook) {\n      return fetchWrapper(endpoint.parse(endpointOptions));\n    }\n\n    const request = (route, parameters) => {\n      return fetchWrapper(endpoint.parse(endpoint.merge(route, parameters)));\n    };\n\n    Object.assign(request, {\n      endpoint,\n      defaults: withDefaults.bind(null, endpoint)\n    });\n    return endpointOptions.request.hook(request, endpointOptions);\n  };\n\n  return Object.assign(newApi, {\n    endpoint,\n    defaults: withDefaults.bind(null, endpoint)\n  });\n}\n\nconst request = withDefaults(endpoint.endpoint, {\n  headers: {\n    \"user-agent\": `octokit-request.js/${VERSION} ${universalUserAgent.getUserAgent()}`\n  }\n});\n\nexports.request = request;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 3682:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nvar register = __webpack_require__(4670)\nvar addHook = __webpack_require__(5549)\nvar removeHook = __webpack_require__(6819)\n\n// bind with array of arguments: https://stackoverflow.com/a/21792913\nvar bind = Function.bind\nvar bindable = bind.bind(bind)\n\nfunction bindApi (hook, state, name) {\n  var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state])\n  hook.api = { remove: removeHookRef }\n  hook.remove = removeHookRef\n\n  ;['before', 'error', 'after', 'wrap'].forEach(function (kind) {\n    var args = name ? [state, kind, name] : [state, kind]\n    hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args)\n  })\n}\n\nfunction HookSingular () {\n  var singularHookName = 'h'\n  var singularHookState = {\n    registry: {}\n  }\n  var singularHook = register.bind(null, singularHookState, singularHookName)\n  bindApi(singularHook, singularHookState, singularHookName)\n  return singularHook\n}\n\nfunction HookCollection () {\n  var state = {\n    registry: {}\n  }\n\n  var hook = register.bind(null, state)\n  bindApi(hook, state)\n\n  return hook\n}\n\nvar collectionHookDeprecationMessageDisplayed = false\nfunction Hook () {\n  if (!collectionHookDeprecationMessageDisplayed) {\n    console.warn('[before-after-hook]: \"Hook()\" repurposing warning, use \"Hook.Collection()\". Read more: https://git.io/upgrade-before-after-hook-to-1.4')\n    collectionHookDeprecationMessageDisplayed = true\n  }\n  return HookCollection()\n}\n\nHook.Singular = HookSingular.bind()\nHook.Collection = HookCollection.bind()\n\nmodule.exports = Hook\n// expose constructors as a named property for TypeScript\nmodule.exports.Hook = Hook\nmodule.exports.Singular = Hook.Singular\nmodule.exports.Collection = Hook.Collection\n\n\n/***/ }),\n\n/***/ 5549:\n/***/ ((module) => {\n\nmodule.exports = addHook;\n\nfunction addHook(state, kind, name, hook) {\n  var orig = hook;\n  if (!state.registry[name]) {\n    state.registry[name] = [];\n  }\n\n  if (kind === \"before\") {\n    hook = function (method, options) {\n      return Promise.resolve()\n        .then(orig.bind(null, options))\n        .then(method.bind(null, options));\n    };\n  }\n\n  if (kind === \"after\") {\n    hook = function (method, options) {\n      var result;\n      return Promise.resolve()\n        .then(method.bind(null, options))\n        .then(function (result_) {\n          result = result_;\n          return orig(result, options);\n        })\n        .then(function () {\n          return result;\n        });\n    };\n  }\n\n  if (kind === \"error\") {\n    hook = function (method, options) {\n      return Promise.resolve()\n        .then(method.bind(null, options))\n        .catch(function (error) {\n          return orig(error, options);\n        });\n    };\n  }\n\n  state.registry[name].push({\n    hook: hook,\n    orig: orig,\n  });\n}\n\n\n/***/ }),\n\n/***/ 4670:\n/***/ ((module) => {\n\nmodule.exports = register;\n\nfunction register(state, name, method, options) {\n  if (typeof method !== \"function\") {\n    throw new Error(\"method for before hook must be a function\");\n  }\n\n  if (!options) {\n    options = {};\n  }\n\n  if (Array.isArray(name)) {\n    return name.reverse().reduce(function (callback, name) {\n      return register.bind(null, state, name, callback, options);\n    }, method)();\n  }\n\n  return Promise.resolve().then(function () {\n    if (!state.registry[name]) {\n      return method(options);\n    }\n\n    return state.registry[name].reduce(function (method, registered) {\n      return registered.hook.bind(null, method, options);\n    }, method)();\n  });\n}\n\n\n/***/ }),\n\n/***/ 6819:\n/***/ ((module) => {\n\nmodule.exports = removeHook;\n\nfunction removeHook(state, name, method) {\n  if (!state.registry[name]) {\n    return;\n  }\n\n  var index = state.registry[name]\n    .map(function (registered) {\n      return registered.orig;\n    })\n    .indexOf(method);\n\n  if (index === -1) {\n    return;\n  }\n\n  state.registry[name].splice(index, 1);\n}\n\n\n/***/ }),\n\n/***/ 8932:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nclass Deprecation extends Error {\n  constructor(message) {\n    super(message); // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n\n    this.name = 'Deprecation';\n  }\n\n}\n\nexports.Deprecation = Deprecation;\n\n\n/***/ }),\n\n/***/ 3287:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\n/*!\n * is-plain-object <https://github.com/jonschlinkert/is-plain-object>\n *\n * Copyright (c) 2014-2017, Jon Schlinkert.\n * Released under the MIT License.\n */\n\nfunction isObject(o) {\n  return Object.prototype.toString.call(o) === '[object Object]';\n}\n\nfunction isPlainObject(o) {\n  var ctor,prot;\n\n  if (isObject(o) === false) return false;\n\n  // If has modified constructor\n  ctor = o.constructor;\n  if (ctor === undefined) return true;\n\n  // If has modified prototype\n  prot = ctor.prototype;\n  if (isObject(prot) === false) return false;\n\n  // If constructor does not have an Object-specific method\n  if (prot.hasOwnProperty('isPrototypeOf') === false) {\n    return false;\n  }\n\n  // Most likely a plain Object\n  return true;\n}\n\nexports.isPlainObject = isPlainObject;\n\n\n/***/ }),\n\n/***/ 467:\n/***/ ((module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar Stream = _interopDefault(__webpack_require__(2413));\nvar http = _interopDefault(__webpack_require__(8605));\nvar Url = _interopDefault(__webpack_require__(8835));\nvar whatwgUrl = _interopDefault(__webpack_require__(8665));\nvar https = _interopDefault(__webpack_require__(7211));\nvar zlib = _interopDefault(__webpack_require__(8761));\n\n// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js\n\n// fix for \"Readable\" isn't a named export issue\nconst Readable = Stream.Readable;\n\nconst BUFFER = Symbol('buffer');\nconst TYPE = Symbol('type');\n\nclass Blob {\n\tconstructor() {\n\t\tthis[TYPE] = '';\n\n\t\tconst blobParts = arguments[0];\n\t\tconst options = arguments[1];\n\n\t\tconst buffers = [];\n\t\tlet size = 0;\n\n\t\tif (blobParts) {\n\t\t\tconst a = blobParts;\n\t\t\tconst length = Number(a.length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tconst element = a[i];\n\t\t\t\tlet buffer;\n\t\t\t\tif (element instanceof Buffer) {\n\t\t\t\t\tbuffer = element;\n\t\t\t\t} else if (ArrayBuffer.isView(element)) {\n\t\t\t\t\tbuffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);\n\t\t\t\t} else if (element instanceof ArrayBuffer) {\n\t\t\t\t\tbuffer = Buffer.from(element);\n\t\t\t\t} else if (element instanceof Blob) {\n\t\t\t\t\tbuffer = element[BUFFER];\n\t\t\t\t} else {\n\t\t\t\t\tbuffer = Buffer.from(typeof element === 'string' ? element : String(element));\n\t\t\t\t}\n\t\t\t\tsize += buffer.length;\n\t\t\t\tbuffers.push(buffer);\n\t\t\t}\n\t\t}\n\n\t\tthis[BUFFER] = Buffer.concat(buffers);\n\n\t\tlet type = options && options.type !== undefined && String(options.type).toLowerCase();\n\t\tif (type && !/[^\\u0020-\\u007E]/.test(type)) {\n\t\t\tthis[TYPE] = type;\n\t\t}\n\t}\n\tget size() {\n\t\treturn this[BUFFER].length;\n\t}\n\tget type() {\n\t\treturn this[TYPE];\n\t}\n\ttext() {\n\t\treturn Promise.resolve(this[BUFFER].toString());\n\t}\n\tarrayBuffer() {\n\t\tconst buf = this[BUFFER];\n\t\tconst ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n\t\treturn Promise.resolve(ab);\n\t}\n\tstream() {\n\t\tconst readable = new Readable();\n\t\treadable._read = function () {};\n\t\treadable.push(this[BUFFER]);\n\t\treadable.push(null);\n\t\treturn readable;\n\t}\n\ttoString() {\n\t\treturn '[object Blob]';\n\t}\n\tslice() {\n\t\tconst size = this.size;\n\n\t\tconst start = arguments[0];\n\t\tconst end = arguments[1];\n\t\tlet relativeStart, relativeEnd;\n\t\tif (start === undefined) {\n\t\t\trelativeStart = 0;\n\t\t} else if (start < 0) {\n\t\t\trelativeStart = Math.max(size + start, 0);\n\t\t} else {\n\t\t\trelativeStart = Math.min(start, size);\n\t\t}\n\t\tif (end === undefined) {\n\t\t\trelativeEnd = size;\n\t\t} else if (end < 0) {\n\t\t\trelativeEnd = Math.max(size + end, 0);\n\t\t} else {\n\t\t\trelativeEnd = Math.min(end, size);\n\t\t}\n\t\tconst span = Math.max(relativeEnd - relativeStart, 0);\n\n\t\tconst buffer = this[BUFFER];\n\t\tconst slicedBuffer = buffer.slice(relativeStart, relativeStart + span);\n\t\tconst blob = new Blob([], { type: arguments[2] });\n\t\tblob[BUFFER] = slicedBuffer;\n\t\treturn blob;\n\t}\n}\n\nObject.defineProperties(Blob.prototype, {\n\tsize: { enumerable: true },\n\ttype: { enumerable: true },\n\tslice: { enumerable: true }\n});\n\nObject.defineProperty(Blob.prototype, Symbol.toStringTag, {\n\tvalue: 'Blob',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\n/**\n * fetch-error.js\n *\n * FetchError interface for operational errors\n */\n\n/**\n * Create FetchError instance\n *\n * @param   String      message      Error message for human\n * @param   String      type         Error type for machine\n * @param   String      systemError  For Node.js system error\n * @return  FetchError\n */\nfunction FetchError(message, type, systemError) {\n  Error.call(this, message);\n\n  this.message = message;\n  this.type = type;\n\n  // when err.type is `system`, err.code contains system error code\n  if (systemError) {\n    this.code = this.errno = systemError.code;\n  }\n\n  // hide custom error implementation details from end-users\n  Error.captureStackTrace(this, this.constructor);\n}\n\nFetchError.prototype = Object.create(Error.prototype);\nFetchError.prototype.constructor = FetchError;\nFetchError.prototype.name = 'FetchError';\n\nlet convert;\ntry {\n\tconvert = __webpack_require__(2877).convert;\n} catch (e) {}\n\nconst INTERNALS = Symbol('Body internals');\n\n// fix an issue where \"PassThrough\" isn't a named export for node <10\nconst PassThrough = Stream.PassThrough;\n\n/**\n * Body mixin\n *\n * Ref: https://fetch.spec.whatwg.org/#body\n *\n * @param   Stream  body  Readable stream\n * @param   Object  opts  Response options\n * @return  Void\n */\nfunction Body(body) {\n\tvar _this = this;\n\n\tvar _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n\t    _ref$size = _ref.size;\n\n\tlet size = _ref$size === undefined ? 0 : _ref$size;\n\tvar _ref$timeout = _ref.timeout;\n\tlet timeout = _ref$timeout === undefined ? 0 : _ref$timeout;\n\n\tif (body == null) {\n\t\t// body is undefined or null\n\t\tbody = null;\n\t} else if (isURLSearchParams(body)) {\n\t\t// body is a URLSearchParams\n\t\tbody = Buffer.from(body.toString());\n\t} else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {\n\t\t// body is ArrayBuffer\n\t\tbody = Buffer.from(body);\n\t} else if (ArrayBuffer.isView(body)) {\n\t\t// body is ArrayBufferView\n\t\tbody = Buffer.from(body.buffer, body.byteOffset, body.byteLength);\n\t} else if (body instanceof Stream) ; else {\n\t\t// none of the above\n\t\t// coerce to string then buffer\n\t\tbody = Buffer.from(String(body));\n\t}\n\tthis[INTERNALS] = {\n\t\tbody,\n\t\tdisturbed: false,\n\t\terror: null\n\t};\n\tthis.size = size;\n\tthis.timeout = timeout;\n\n\tif (body instanceof Stream) {\n\t\tbody.on('error', function (err) {\n\t\t\tconst error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err);\n\t\t\t_this[INTERNALS].error = error;\n\t\t});\n\t}\n}\n\nBody.prototype = {\n\tget body() {\n\t\treturn this[INTERNALS].body;\n\t},\n\n\tget bodyUsed() {\n\t\treturn this[INTERNALS].disturbed;\n\t},\n\n\t/**\n  * Decode response as ArrayBuffer\n  *\n  * @return  Promise\n  */\n\tarrayBuffer() {\n\t\treturn consumeBody.call(this).then(function (buf) {\n\t\t\treturn buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n\t\t});\n\t},\n\n\t/**\n  * Return raw response as Blob\n  *\n  * @return Promise\n  */\n\tblob() {\n\t\tlet ct = this.headers && this.headers.get('content-type') || '';\n\t\treturn consumeBody.call(this).then(function (buf) {\n\t\t\treturn Object.assign(\n\t\t\t// Prevent copying\n\t\t\tnew Blob([], {\n\t\t\t\ttype: ct.toLowerCase()\n\t\t\t}), {\n\t\t\t\t[BUFFER]: buf\n\t\t\t});\n\t\t});\n\t},\n\n\t/**\n  * Decode response as json\n  *\n  * @return  Promise\n  */\n\tjson() {\n\t\tvar _this2 = this;\n\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buffer.toString());\n\t\t\t} catch (err) {\n\t\t\t\treturn Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n  * Decode response as text\n  *\n  * @return  Promise\n  */\n\ttext() {\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\treturn buffer.toString();\n\t\t});\n\t},\n\n\t/**\n  * Decode response as buffer (non-spec api)\n  *\n  * @return  Promise\n  */\n\tbuffer() {\n\t\treturn consumeBody.call(this);\n\t},\n\n\t/**\n  * Decode response as text, while automatically detecting the encoding and\n  * trying to decode to UTF-8 (non-spec api)\n  *\n  * @return  Promise\n  */\n\ttextConverted() {\n\t\tvar _this3 = this;\n\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\treturn convertBody(buffer, _this3.headers);\n\t\t});\n\t}\n};\n\n// In browsers, all properties are enumerable.\nObject.defineProperties(Body.prototype, {\n\tbody: { enumerable: true },\n\tbodyUsed: { enumerable: true },\n\tarrayBuffer: { enumerable: true },\n\tblob: { enumerable: true },\n\tjson: { enumerable: true },\n\ttext: { enumerable: true }\n});\n\nBody.mixIn = function (proto) {\n\tfor (const name of Object.getOwnPropertyNames(Body.prototype)) {\n\t\t// istanbul ignore else: future proof\n\t\tif (!(name in proto)) {\n\t\t\tconst desc = Object.getOwnPropertyDescriptor(Body.prototype, name);\n\t\t\tObject.defineProperty(proto, name, desc);\n\t\t}\n\t}\n};\n\n/**\n * Consume and convert an entire Body to a Buffer.\n *\n * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body\n *\n * @return  Promise\n */\nfunction consumeBody() {\n\tvar _this4 = this;\n\n\tif (this[INTERNALS].disturbed) {\n\t\treturn Body.Promise.reject(new TypeError(`body used already for: ${this.url}`));\n\t}\n\n\tthis[INTERNALS].disturbed = true;\n\n\tif (this[INTERNALS].error) {\n\t\treturn Body.Promise.reject(this[INTERNALS].error);\n\t}\n\n\tlet body = this.body;\n\n\t// body is null\n\tif (body === null) {\n\t\treturn Body.Promise.resolve(Buffer.alloc(0));\n\t}\n\n\t// body is blob\n\tif (isBlob(body)) {\n\t\tbody = body.stream();\n\t}\n\n\t// body is buffer\n\tif (Buffer.isBuffer(body)) {\n\t\treturn Body.Promise.resolve(body);\n\t}\n\n\t// istanbul ignore if: should never happen\n\tif (!(body instanceof Stream)) {\n\t\treturn Body.Promise.resolve(Buffer.alloc(0));\n\t}\n\n\t// body is stream\n\t// get ready to actually consume the body\n\tlet accum = [];\n\tlet accumBytes = 0;\n\tlet abort = false;\n\n\treturn new Body.Promise(function (resolve, reject) {\n\t\tlet resTimeout;\n\n\t\t// allow timeout on slow response body\n\t\tif (_this4.timeout) {\n\t\t\tresTimeout = setTimeout(function () {\n\t\t\t\tabort = true;\n\t\t\t\treject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout'));\n\t\t\t}, _this4.timeout);\n\t\t}\n\n\t\t// handle stream errors\n\t\tbody.on('error', function (err) {\n\t\t\tif (err.name === 'AbortError') {\n\t\t\t\t// if the request was aborted, reject with this Error\n\t\t\t\tabort = true;\n\t\t\t\treject(err);\n\t\t\t} else {\n\t\t\t\t// other errors, such as incorrect content-encoding\n\t\t\t\treject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err));\n\t\t\t}\n\t\t});\n\n\t\tbody.on('data', function (chunk) {\n\t\t\tif (abort || chunk === null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (_this4.size && accumBytes + chunk.length > _this4.size) {\n\t\t\t\tabort = true;\n\t\t\t\treject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size'));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\taccumBytes += chunk.length;\n\t\t\taccum.push(chunk);\n\t\t});\n\n\t\tbody.on('end', function () {\n\t\t\tif (abort) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tclearTimeout(resTimeout);\n\n\t\t\ttry {\n\t\t\t\tresolve(Buffer.concat(accum, accumBytes));\n\t\t\t} catch (err) {\n\t\t\t\t// handle streams that have accumulated too much data (issue #414)\n\t\t\t\treject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err));\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Detect buffer encoding and convert to target encoding\n * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding\n *\n * @param   Buffer  buffer    Incoming buffer\n * @param   String  encoding  Target encoding\n * @return  String\n */\nfunction convertBody(buffer, headers) {\n\tif (typeof convert !== 'function') {\n\t\tthrow new Error('The package `encoding` must be installed to use the textConverted() function');\n\t}\n\n\tconst ct = headers.get('content-type');\n\tlet charset = 'utf-8';\n\tlet res, str;\n\n\t// header\n\tif (ct) {\n\t\tres = /charset=([^;]*)/i.exec(ct);\n\t}\n\n\t// no charset in content type, peek at response body for at most 1024 bytes\n\tstr = buffer.slice(0, 1024).toString();\n\n\t// html5\n\tif (!res && str) {\n\t\tres = /<meta.+?charset=(['\"])(.+?)\\1/i.exec(str);\n\t}\n\n\t// html4\n\tif (!res && str) {\n\t\tres = /<meta[\\s]+?http-equiv=(['\"])content-type\\1[\\s]+?content=(['\"])(.+?)\\2/i.exec(str);\n\t\tif (!res) {\n\t\t\tres = /<meta[\\s]+?content=(['\"])(.+?)\\1[\\s]+?http-equiv=(['\"])content-type\\3/i.exec(str);\n\t\t\tif (res) {\n\t\t\t\tres.pop(); // drop last quote\n\t\t\t}\n\t\t}\n\n\t\tif (res) {\n\t\t\tres = /charset=(.*)/i.exec(res.pop());\n\t\t}\n\t}\n\n\t// xml\n\tif (!res && str) {\n\t\tres = /<\\?xml.+?encoding=(['\"])(.+?)\\1/i.exec(str);\n\t}\n\n\t// found charset\n\tif (res) {\n\t\tcharset = res.pop();\n\n\t\t// prevent decode issues when sites use incorrect encoding\n\t\t// ref: https://hsivonen.fi/encoding-menu/\n\t\tif (charset === 'gb2312' || charset === 'gbk') {\n\t\t\tcharset = 'gb18030';\n\t\t}\n\t}\n\n\t// turn raw buffers into a single utf-8 buffer\n\treturn convert(buffer, 'UTF-8', charset).toString();\n}\n\n/**\n * Detect a URLSearchParams object\n * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143\n *\n * @param   Object  obj     Object to detect by type or brand\n * @return  String\n */\nfunction isURLSearchParams(obj) {\n\t// Duck-typing as a necessary condition.\n\tif (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') {\n\t\treturn false;\n\t}\n\n\t// Brand-checking and more duck-typing as optional condition.\n\treturn obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';\n}\n\n/**\n * Check if `obj` is a W3C `Blob` object (which `File` inherits from)\n * @param  {*} obj\n * @return {boolean}\n */\nfunction isBlob(obj) {\n\treturn typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]);\n}\n\n/**\n * Clone body given Res/Req instance\n *\n * @param   Mixed  instance  Response or Request instance\n * @return  Mixed\n */\nfunction clone(instance) {\n\tlet p1, p2;\n\tlet body = instance.body;\n\n\t// don't allow cloning a used body\n\tif (instance.bodyUsed) {\n\t\tthrow new Error('cannot clone body after it is used');\n\t}\n\n\t// check that body is a stream and not form-data object\n\t// note: we can't clone the form-data object without having it as a dependency\n\tif (body instanceof Stream && typeof body.getBoundary !== 'function') {\n\t\t// tee instance body\n\t\tp1 = new PassThrough();\n\t\tp2 = new PassThrough();\n\t\tbody.pipe(p1);\n\t\tbody.pipe(p2);\n\t\t// set instance body to teed body and return the other teed body\n\t\tinstance[INTERNALS].body = p1;\n\t\tbody = p2;\n\t}\n\n\treturn body;\n}\n\n/**\n * Performs the operation \"extract a `Content-Type` value from |object|\" as\n * specified in the specification:\n * https://fetch.spec.whatwg.org/#concept-bodyinit-extract\n *\n * This function assumes that instance.body is present.\n *\n * @param   Mixed  instance  Any options.body input\n */\nfunction extractContentType(body) {\n\tif (body === null) {\n\t\t// body is null\n\t\treturn null;\n\t} else if (typeof body === 'string') {\n\t\t// body is string\n\t\treturn 'text/plain;charset=UTF-8';\n\t} else if (isURLSearchParams(body)) {\n\t\t// body is a URLSearchParams\n\t\treturn 'application/x-www-form-urlencoded;charset=UTF-8';\n\t} else if (isBlob(body)) {\n\t\t// body is blob\n\t\treturn body.type || null;\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\treturn null;\n\t} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {\n\t\t// body is ArrayBuffer\n\t\treturn null;\n\t} else if (ArrayBuffer.isView(body)) {\n\t\t// body is ArrayBufferView\n\t\treturn null;\n\t} else if (typeof body.getBoundary === 'function') {\n\t\t// detect form data input from form-data module\n\t\treturn `multipart/form-data;boundary=${body.getBoundary()}`;\n\t} else if (body instanceof Stream) {\n\t\t// body is stream\n\t\t// can't really do much about this\n\t\treturn null;\n\t} else {\n\t\t// Body constructor defaults other things to string\n\t\treturn 'text/plain;charset=UTF-8';\n\t}\n}\n\n/**\n * The Fetch Standard treats this as if \"total bytes\" is a property on the body.\n * For us, we have to explicitly get it with a function.\n *\n * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes\n *\n * @param   Body    instance   Instance of Body\n * @return  Number?            Number of bytes, or null if not possible\n */\nfunction getTotalBytes(instance) {\n\tconst body = instance.body;\n\n\n\tif (body === null) {\n\t\t// body is null\n\t\treturn 0;\n\t} else if (isBlob(body)) {\n\t\treturn body.size;\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\treturn body.length;\n\t} else if (body && typeof body.getLengthSync === 'function') {\n\t\t// detect form data input from form-data module\n\t\tif (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x\n\t\tbody.hasKnownLength && body.hasKnownLength()) {\n\t\t\t// 2.x\n\t\t\treturn body.getLengthSync();\n\t\t}\n\t\treturn null;\n\t} else {\n\t\t// body is stream\n\t\treturn null;\n\t}\n}\n\n/**\n * Write a Body to a Node.js WritableStream (e.g. http.Request) object.\n *\n * @param   Body    instance   Instance of Body\n * @return  Void\n */\nfunction writeToStream(dest, instance) {\n\tconst body = instance.body;\n\n\n\tif (body === null) {\n\t\t// body is null\n\t\tdest.end();\n\t} else if (isBlob(body)) {\n\t\tbody.stream().pipe(dest);\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\tdest.write(body);\n\t\tdest.end();\n\t} else {\n\t\t// body is stream\n\t\tbody.pipe(dest);\n\t}\n}\n\n// expose Promise\nBody.Promise = global.Promise;\n\n/**\n * headers.js\n *\n * Headers class offers convenient helpers\n */\n\nconst invalidTokenRegex = /[^\\^_`a-zA-Z\\-0-9!#$%&'*+.|~]/;\nconst invalidHeaderCharRegex = /[^\\t\\x20-\\x7e\\x80-\\xff]/;\n\nfunction validateName(name) {\n\tname = `${name}`;\n\tif (invalidTokenRegex.test(name) || name === '') {\n\t\tthrow new TypeError(`${name} is not a legal HTTP header name`);\n\t}\n}\n\nfunction validateValue(value) {\n\tvalue = `${value}`;\n\tif (invalidHeaderCharRegex.test(value)) {\n\t\tthrow new TypeError(`${value} is not a legal HTTP header value`);\n\t}\n}\n\n/**\n * Find the key in the map object given a header name.\n *\n * Returns undefined if not found.\n *\n * @param   String  name  Header name\n * @return  String|Undefined\n */\nfunction find(map, name) {\n\tname = name.toLowerCase();\n\tfor (const key in map) {\n\t\tif (key.toLowerCase() === name) {\n\t\t\treturn key;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nconst MAP = Symbol('map');\nclass Headers {\n\t/**\n  * Headers class\n  *\n  * @param   Object  headers  Response headers\n  * @return  Void\n  */\n\tconstructor() {\n\t\tlet init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;\n\n\t\tthis[MAP] = Object.create(null);\n\n\t\tif (init instanceof Headers) {\n\t\t\tconst rawHeaders = init.raw();\n\t\t\tconst headerNames = Object.keys(rawHeaders);\n\n\t\t\tfor (const headerName of headerNames) {\n\t\t\t\tfor (const value of rawHeaders[headerName]) {\n\t\t\t\t\tthis.append(headerName, value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// We don't worry about converting prop to ByteString here as append()\n\t\t// will handle it.\n\t\tif (init == null) ; else if (typeof init === 'object') {\n\t\t\tconst method = init[Symbol.iterator];\n\t\t\tif (method != null) {\n\t\t\t\tif (typeof method !== 'function') {\n\t\t\t\t\tthrow new TypeError('Header pairs must be iterable');\n\t\t\t\t}\n\n\t\t\t\t// sequence<sequence<ByteString>>\n\t\t\t\t// Note: per spec we have to first exhaust the lists then process them\n\t\t\t\tconst pairs = [];\n\t\t\t\tfor (const pair of init) {\n\t\t\t\t\tif (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {\n\t\t\t\t\t\tthrow new TypeError('Each header pair must be iterable');\n\t\t\t\t\t}\n\t\t\t\t\tpairs.push(Array.from(pair));\n\t\t\t\t}\n\n\t\t\t\tfor (const pair of pairs) {\n\t\t\t\t\tif (pair.length !== 2) {\n\t\t\t\t\t\tthrow new TypeError('Each header pair must be a name/value tuple');\n\t\t\t\t\t}\n\t\t\t\t\tthis.append(pair[0], pair[1]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// record<ByteString, ByteString>\n\t\t\t\tfor (const key of Object.keys(init)) {\n\t\t\t\t\tconst value = init[key];\n\t\t\t\t\tthis.append(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new TypeError('Provided initializer must be an object');\n\t\t}\n\t}\n\n\t/**\n  * Return combined header value given name\n  *\n  * @param   String  name  Header name\n  * @return  Mixed\n  */\n\tget(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key === undefined) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this[MAP][key].join(', ');\n\t}\n\n\t/**\n  * Iterate over all headers\n  *\n  * @param   Function  callback  Executed for each item with parameters (value, name, thisArg)\n  * @param   Boolean   thisArg   `this` context for callback function\n  * @return  Void\n  */\n\tforEach(callback) {\n\t\tlet thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;\n\n\t\tlet pairs = getHeaders(this);\n\t\tlet i = 0;\n\t\twhile (i < pairs.length) {\n\t\t\tvar _pairs$i = pairs[i];\n\t\t\tconst name = _pairs$i[0],\n\t\t\t      value = _pairs$i[1];\n\n\t\t\tcallback.call(thisArg, value, name, this);\n\t\t\tpairs = getHeaders(this);\n\t\t\ti++;\n\t\t}\n\t}\n\n\t/**\n  * Overwrite header values given name\n  *\n  * @param   String  name   Header name\n  * @param   String  value  Header value\n  * @return  Void\n  */\n\tset(name, value) {\n\t\tname = `${name}`;\n\t\tvalue = `${value}`;\n\t\tvalidateName(name);\n\t\tvalidateValue(value);\n\t\tconst key = find(this[MAP], name);\n\t\tthis[MAP][key !== undefined ? key : name] = [value];\n\t}\n\n\t/**\n  * Append a value onto existing header\n  *\n  * @param   String  name   Header name\n  * @param   String  value  Header value\n  * @return  Void\n  */\n\tappend(name, value) {\n\t\tname = `${name}`;\n\t\tvalue = `${value}`;\n\t\tvalidateName(name);\n\t\tvalidateValue(value);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key !== undefined) {\n\t\t\tthis[MAP][key].push(value);\n\t\t} else {\n\t\t\tthis[MAP][name] = [value];\n\t\t}\n\t}\n\n\t/**\n  * Check for header name existence\n  *\n  * @param   String   name  Header name\n  * @return  Boolean\n  */\n\thas(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\treturn find(this[MAP], name) !== undefined;\n\t}\n\n\t/**\n  * Delete all header values given name\n  *\n  * @param   String  name  Header name\n  * @return  Void\n  */\n\tdelete(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key !== undefined) {\n\t\t\tdelete this[MAP][key];\n\t\t}\n\t}\n\n\t/**\n  * Return raw headers (non-spec api)\n  *\n  * @return  Object\n  */\n\traw() {\n\t\treturn this[MAP];\n\t}\n\n\t/**\n  * Get an iterator on keys.\n  *\n  * @return  Iterator\n  */\n\tkeys() {\n\t\treturn createHeadersIterator(this, 'key');\n\t}\n\n\t/**\n  * Get an iterator on values.\n  *\n  * @return  Iterator\n  */\n\tvalues() {\n\t\treturn createHeadersIterator(this, 'value');\n\t}\n\n\t/**\n  * Get an iterator on entries.\n  *\n  * This is the default iterator of the Headers object.\n  *\n  * @return  Iterator\n  */\n\t[Symbol.iterator]() {\n\t\treturn createHeadersIterator(this, 'key+value');\n\t}\n}\nHeaders.prototype.entries = Headers.prototype[Symbol.iterator];\n\nObject.defineProperty(Headers.prototype, Symbol.toStringTag, {\n\tvalue: 'Headers',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nObject.defineProperties(Headers.prototype, {\n\tget: { enumerable: true },\n\tforEach: { enumerable: true },\n\tset: { enumerable: true },\n\tappend: { enumerable: true },\n\thas: { enumerable: true },\n\tdelete: { enumerable: true },\n\tkeys: { enumerable: true },\n\tvalues: { enumerable: true },\n\tentries: { enumerable: true }\n});\n\nfunction getHeaders(headers) {\n\tlet kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value';\n\n\tconst keys = Object.keys(headers[MAP]).sort();\n\treturn keys.map(kind === 'key' ? function (k) {\n\t\treturn k.toLowerCase();\n\t} : kind === 'value' ? function (k) {\n\t\treturn headers[MAP][k].join(', ');\n\t} : function (k) {\n\t\treturn [k.toLowerCase(), headers[MAP][k].join(', ')];\n\t});\n}\n\nconst INTERNAL = Symbol('internal');\n\nfunction createHeadersIterator(target, kind) {\n\tconst iterator = Object.create(HeadersIteratorPrototype);\n\titerator[INTERNAL] = {\n\t\ttarget,\n\t\tkind,\n\t\tindex: 0\n\t};\n\treturn iterator;\n}\n\nconst HeadersIteratorPrototype = Object.setPrototypeOf({\n\tnext() {\n\t\t// istanbul ignore if\n\t\tif (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {\n\t\t\tthrow new TypeError('Value of `this` is not a HeadersIterator');\n\t\t}\n\n\t\tvar _INTERNAL = this[INTERNAL];\n\t\tconst target = _INTERNAL.target,\n\t\t      kind = _INTERNAL.kind,\n\t\t      index = _INTERNAL.index;\n\n\t\tconst values = getHeaders(target, kind);\n\t\tconst len = values.length;\n\t\tif (index >= len) {\n\t\t\treturn {\n\t\t\t\tvalue: undefined,\n\t\t\t\tdone: true\n\t\t\t};\n\t\t}\n\n\t\tthis[INTERNAL].index = index + 1;\n\n\t\treturn {\n\t\t\tvalue: values[index],\n\t\t\tdone: false\n\t\t};\n\t}\n}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));\n\nObject.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {\n\tvalue: 'HeadersIterator',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\n/**\n * Export the Headers object in a form that Node.js can consume.\n *\n * @param   Headers  headers\n * @return  Object\n */\nfunction exportNodeCompatibleHeaders(headers) {\n\tconst obj = Object.assign({ __proto__: null }, headers[MAP]);\n\n\t// http.request() only supports string as Host header. This hack makes\n\t// specifying custom Host header possible.\n\tconst hostHeaderKey = find(headers[MAP], 'Host');\n\tif (hostHeaderKey !== undefined) {\n\t\tobj[hostHeaderKey] = obj[hostHeaderKey][0];\n\t}\n\n\treturn obj;\n}\n\n/**\n * Create a Headers object from an object of headers, ignoring those that do\n * not conform to HTTP grammar productions.\n *\n * @param   Object  obj  Object of headers\n * @return  Headers\n */\nfunction createHeadersLenient(obj) {\n\tconst headers = new Headers();\n\tfor (const name of Object.keys(obj)) {\n\t\tif (invalidTokenRegex.test(name)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (Array.isArray(obj[name])) {\n\t\t\tfor (const val of obj[name]) {\n\t\t\t\tif (invalidHeaderCharRegex.test(val)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (headers[MAP][name] === undefined) {\n\t\t\t\t\theaders[MAP][name] = [val];\n\t\t\t\t} else {\n\t\t\t\t\theaders[MAP][name].push(val);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (!invalidHeaderCharRegex.test(obj[name])) {\n\t\t\theaders[MAP][name] = [obj[name]];\n\t\t}\n\t}\n\treturn headers;\n}\n\nconst INTERNALS$1 = Symbol('Response internals');\n\n// fix an issue where \"STATUS_CODES\" aren't a named export for node <10\nconst STATUS_CODES = http.STATUS_CODES;\n\n/**\n * Response class\n *\n * @param   Stream  body  Readable stream\n * @param   Object  opts  Response options\n * @return  Void\n */\nclass Response {\n\tconstructor() {\n\t\tlet body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n\t\tlet opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n\t\tBody.call(this, body, opts);\n\n\t\tconst status = opts.status || 200;\n\t\tconst headers = new Headers(opts.headers);\n\n\t\tif (body != null && !headers.has('Content-Type')) {\n\t\t\tconst contentType = extractContentType(body);\n\t\t\tif (contentType) {\n\t\t\t\theaders.append('Content-Type', contentType);\n\t\t\t}\n\t\t}\n\n\t\tthis[INTERNALS$1] = {\n\t\t\turl: opts.url,\n\t\t\tstatus,\n\t\t\tstatusText: opts.statusText || STATUS_CODES[status],\n\t\t\theaders,\n\t\t\tcounter: opts.counter\n\t\t};\n\t}\n\n\tget url() {\n\t\treturn this[INTERNALS$1].url || '';\n\t}\n\n\tget status() {\n\t\treturn this[INTERNALS$1].status;\n\t}\n\n\t/**\n  * Convenience property representing if the request ended normally\n  */\n\tget ok() {\n\t\treturn this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300;\n\t}\n\n\tget redirected() {\n\t\treturn this[INTERNALS$1].counter > 0;\n\t}\n\n\tget statusText() {\n\t\treturn this[INTERNALS$1].statusText;\n\t}\n\n\tget headers() {\n\t\treturn this[INTERNALS$1].headers;\n\t}\n\n\t/**\n  * Clone this response\n  *\n  * @return  Response\n  */\n\tclone() {\n\t\treturn new Response(clone(this), {\n\t\t\turl: this.url,\n\t\t\tstatus: this.status,\n\t\t\tstatusText: this.statusText,\n\t\t\theaders: this.headers,\n\t\t\tok: this.ok,\n\t\t\tredirected: this.redirected\n\t\t});\n\t}\n}\n\nBody.mixIn(Response.prototype);\n\nObject.defineProperties(Response.prototype, {\n\turl: { enumerable: true },\n\tstatus: { enumerable: true },\n\tok: { enumerable: true },\n\tredirected: { enumerable: true },\n\tstatusText: { enumerable: true },\n\theaders: { enumerable: true },\n\tclone: { enumerable: true }\n});\n\nObject.defineProperty(Response.prototype, Symbol.toStringTag, {\n\tvalue: 'Response',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nconst INTERNALS$2 = Symbol('Request internals');\nconst URL = Url.URL || whatwgUrl.URL;\n\n// fix an issue where \"format\", \"parse\" aren't a named export for node <10\nconst parse_url = Url.parse;\nconst format_url = Url.format;\n\n/**\n * Wrapper around `new URL` to handle arbitrary URLs\n *\n * @param  {string} urlStr\n * @return {void}\n */\nfunction parseURL(urlStr) {\n\t/*\n \tCheck whether the URL is absolute or not\n \t\tScheme: https://tools.ietf.org/html/rfc3986#section-3.1\n \tAbsolute URL: https://tools.ietf.org/html/rfc3986#section-4.3\n */\n\tif (/^[a-zA-Z][a-zA-Z\\d+\\-.]*:/.exec(urlStr)) {\n\t\turlStr = new URL(urlStr).toString();\n\t}\n\n\t// Fallback to old implementation for arbitrary URLs\n\treturn parse_url(urlStr);\n}\n\nconst streamDestructionSupported = 'destroy' in Stream.Readable.prototype;\n\n/**\n * Check if a value is an instance of Request.\n *\n * @param   Mixed   input\n * @return  Boolean\n */\nfunction isRequest(input) {\n\treturn typeof input === 'object' && typeof input[INTERNALS$2] === 'object';\n}\n\nfunction isAbortSignal(signal) {\n\tconst proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal);\n\treturn !!(proto && proto.constructor.name === 'AbortSignal');\n}\n\n/**\n * Request class\n *\n * @param   Mixed   input  Url or Request instance\n * @param   Object  init   Custom options\n * @return  Void\n */\nclass Request {\n\tconstructor(input) {\n\t\tlet init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n\t\tlet parsedURL;\n\n\t\t// normalize input\n\t\tif (!isRequest(input)) {\n\t\t\tif (input && input.href) {\n\t\t\t\t// in order to support Node.js' Url objects; though WHATWG's URL objects\n\t\t\t\t// will fall into this branch also (since their `toString()` will return\n\t\t\t\t// `href` property anyway)\n\t\t\t\tparsedURL = parseURL(input.href);\n\t\t\t} else {\n\t\t\t\t// coerce input to a string before attempting to parse\n\t\t\t\tparsedURL = parseURL(`${input}`);\n\t\t\t}\n\t\t\tinput = {};\n\t\t} else {\n\t\t\tparsedURL = parseURL(input.url);\n\t\t}\n\n\t\tlet method = init.method || input.method || 'GET';\n\t\tmethod = method.toUpperCase();\n\n\t\tif ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) {\n\t\t\tthrow new TypeError('Request with GET/HEAD method cannot have body');\n\t\t}\n\n\t\tlet inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null;\n\n\t\tBody.call(this, inputBody, {\n\t\t\ttimeout: init.timeout || input.timeout || 0,\n\t\t\tsize: init.size || input.size || 0\n\t\t});\n\n\t\tconst headers = new Headers(init.headers || input.headers || {});\n\n\t\tif (inputBody != null && !headers.has('Content-Type')) {\n\t\t\tconst contentType = extractContentType(inputBody);\n\t\t\tif (contentType) {\n\t\t\t\theaders.append('Content-Type', contentType);\n\t\t\t}\n\t\t}\n\n\t\tlet signal = isRequest(input) ? input.signal : null;\n\t\tif ('signal' in init) signal = init.signal;\n\n\t\tif (signal != null && !isAbortSignal(signal)) {\n\t\t\tthrow new TypeError('Expected signal to be an instanceof AbortSignal');\n\t\t}\n\n\t\tthis[INTERNALS$2] = {\n\t\t\tmethod,\n\t\t\tredirect: init.redirect || input.redirect || 'follow',\n\t\t\theaders,\n\t\t\tparsedURL,\n\t\t\tsignal\n\t\t};\n\n\t\t// node-fetch-only options\n\t\tthis.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;\n\t\tthis.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;\n\t\tthis.counter = init.counter || input.counter || 0;\n\t\tthis.agent = init.agent || input.agent;\n\t}\n\n\tget method() {\n\t\treturn this[INTERNALS$2].method;\n\t}\n\n\tget url() {\n\t\treturn format_url(this[INTERNALS$2].parsedURL);\n\t}\n\n\tget headers() {\n\t\treturn this[INTERNALS$2].headers;\n\t}\n\n\tget redirect() {\n\t\treturn this[INTERNALS$2].redirect;\n\t}\n\n\tget signal() {\n\t\treturn this[INTERNALS$2].signal;\n\t}\n\n\t/**\n  * Clone this request\n  *\n  * @return  Request\n  */\n\tclone() {\n\t\treturn new Request(this);\n\t}\n}\n\nBody.mixIn(Request.prototype);\n\nObject.defineProperty(Request.prototype, Symbol.toStringTag, {\n\tvalue: 'Request',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nObject.defineProperties(Request.prototype, {\n\tmethod: { enumerable: true },\n\turl: { enumerable: true },\n\theaders: { enumerable: true },\n\tredirect: { enumerable: true },\n\tclone: { enumerable: true },\n\tsignal: { enumerable: true }\n});\n\n/**\n * Convert a Request to Node.js http request options.\n *\n * @param   Request  A Request instance\n * @return  Object   The options object to be passed to http.request\n */\nfunction getNodeRequestOptions(request) {\n\tconst parsedURL = request[INTERNALS$2].parsedURL;\n\tconst headers = new Headers(request[INTERNALS$2].headers);\n\n\t// fetch step 1.3\n\tif (!headers.has('Accept')) {\n\t\theaders.set('Accept', '*/*');\n\t}\n\n\t// Basic fetch\n\tif (!parsedURL.protocol || !parsedURL.hostname) {\n\t\tthrow new TypeError('Only absolute URLs are supported');\n\t}\n\n\tif (!/^https?:$/.test(parsedURL.protocol)) {\n\t\tthrow new TypeError('Only HTTP(S) protocols are supported');\n\t}\n\n\tif (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) {\n\t\tthrow new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8');\n\t}\n\n\t// HTTP-network-or-cache fetch steps 2.4-2.7\n\tlet contentLengthValue = null;\n\tif (request.body == null && /^(POST|PUT)$/i.test(request.method)) {\n\t\tcontentLengthValue = '0';\n\t}\n\tif (request.body != null) {\n\t\tconst totalBytes = getTotalBytes(request);\n\t\tif (typeof totalBytes === 'number') {\n\t\t\tcontentLengthValue = String(totalBytes);\n\t\t}\n\t}\n\tif (contentLengthValue) {\n\t\theaders.set('Content-Length', contentLengthValue);\n\t}\n\n\t// HTTP-network-or-cache fetch step 2.11\n\tif (!headers.has('User-Agent')) {\n\t\theaders.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');\n\t}\n\n\t// HTTP-network-or-cache fetch step 2.15\n\tif (request.compress && !headers.has('Accept-Encoding')) {\n\t\theaders.set('Accept-Encoding', 'gzip,deflate');\n\t}\n\n\tlet agent = request.agent;\n\tif (typeof agent === 'function') {\n\t\tagent = agent(parsedURL);\n\t}\n\n\tif (!headers.has('Connection') && !agent) {\n\t\theaders.set('Connection', 'close');\n\t}\n\n\t// HTTP-network fetch step 4.2\n\t// chunked encoding is handled by Node.js\n\n\treturn Object.assign({}, parsedURL, {\n\t\tmethod: request.method,\n\t\theaders: exportNodeCompatibleHeaders(headers),\n\t\tagent\n\t});\n}\n\n/**\n * abort-error.js\n *\n * AbortError interface for cancelled requests\n */\n\n/**\n * Create AbortError instance\n *\n * @param   String      message      Error message for human\n * @return  AbortError\n */\nfunction AbortError(message) {\n  Error.call(this, message);\n\n  this.type = 'aborted';\n  this.message = message;\n\n  // hide custom error implementation details from end-users\n  Error.captureStackTrace(this, this.constructor);\n}\n\nAbortError.prototype = Object.create(Error.prototype);\nAbortError.prototype.constructor = AbortError;\nAbortError.prototype.name = 'AbortError';\n\n// fix an issue where \"PassThrough\", \"resolve\" aren't a named export for node <10\nconst PassThrough$1 = Stream.PassThrough;\nconst resolve_url = Url.resolve;\n\n/**\n * Fetch function\n *\n * @param   Mixed    url   Absolute url or Request instance\n * @param   Object   opts  Fetch options\n * @return  Promise\n */\nfunction fetch(url, opts) {\n\n\t// allow custom promise\n\tif (!fetch.Promise) {\n\t\tthrow new Error('native promise missing, set fetch.Promise to your favorite alternative');\n\t}\n\n\tBody.Promise = fetch.Promise;\n\n\t// wrap http.request into fetch\n\treturn new fetch.Promise(function (resolve, reject) {\n\t\t// build request object\n\t\tconst request = new Request(url, opts);\n\t\tconst options = getNodeRequestOptions(request);\n\n\t\tconst send = (options.protocol === 'https:' ? https : http).request;\n\t\tconst signal = request.signal;\n\n\t\tlet response = null;\n\n\t\tconst abort = function abort() {\n\t\t\tlet error = new AbortError('The user aborted a request.');\n\t\t\treject(error);\n\t\t\tif (request.body && request.body instanceof Stream.Readable) {\n\t\t\t\trequest.body.destroy(error);\n\t\t\t}\n\t\t\tif (!response || !response.body) return;\n\t\t\tresponse.body.emit('error', error);\n\t\t};\n\n\t\tif (signal && signal.aborted) {\n\t\t\tabort();\n\t\t\treturn;\n\t\t}\n\n\t\tconst abortAndFinalize = function abortAndFinalize() {\n\t\t\tabort();\n\t\t\tfinalize();\n\t\t};\n\n\t\t// send request\n\t\tconst req = send(options);\n\t\tlet reqTimeout;\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', abortAndFinalize);\n\t\t}\n\n\t\tfunction finalize() {\n\t\t\treq.abort();\n\t\t\tif (signal) signal.removeEventListener('abort', abortAndFinalize);\n\t\t\tclearTimeout(reqTimeout);\n\t\t}\n\n\t\tif (request.timeout) {\n\t\t\treq.once('socket', function (socket) {\n\t\t\t\treqTimeout = setTimeout(function () {\n\t\t\t\t\treject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));\n\t\t\t\t\tfinalize();\n\t\t\t\t}, request.timeout);\n\t\t\t});\n\t\t}\n\n\t\treq.on('error', function (err) {\n\t\t\treject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));\n\t\t\tfinalize();\n\t\t});\n\n\t\treq.on('response', function (res) {\n\t\t\tclearTimeout(reqTimeout);\n\n\t\t\tconst headers = createHeadersLenient(res.headers);\n\n\t\t\t// HTTP fetch step 5\n\t\t\tif (fetch.isRedirect(res.statusCode)) {\n\t\t\t\t// HTTP fetch step 5.2\n\t\t\t\tconst location = headers.get('Location');\n\n\t\t\t\t// HTTP fetch step 5.3\n\t\t\t\tconst locationURL = location === null ? null : resolve_url(request.url, location);\n\n\t\t\t\t// HTTP fetch step 5.5\n\t\t\t\tswitch (request.redirect) {\n\t\t\t\t\tcase 'error':\n\t\t\t\t\t\treject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase 'manual':\n\t\t\t\t\t\t// node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.\n\t\t\t\t\t\tif (locationURL !== null) {\n\t\t\t\t\t\t\t// handle corrupted header\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\theaders.set('Location', locationURL);\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t// istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request\n\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'follow':\n\t\t\t\t\t\t// HTTP-redirect fetch step 2\n\t\t\t\t\t\tif (locationURL === null) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 5\n\t\t\t\t\t\tif (request.counter >= request.follow) {\n\t\t\t\t\t\t\treject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));\n\t\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 6 (counter increment)\n\t\t\t\t\t\t// Create a new Request object.\n\t\t\t\t\t\tconst requestOpts = {\n\t\t\t\t\t\t\theaders: new Headers(request.headers),\n\t\t\t\t\t\t\tfollow: request.follow,\n\t\t\t\t\t\t\tcounter: request.counter + 1,\n\t\t\t\t\t\t\tagent: request.agent,\n\t\t\t\t\t\t\tcompress: request.compress,\n\t\t\t\t\t\t\tmethod: request.method,\n\t\t\t\t\t\t\tbody: request.body,\n\t\t\t\t\t\t\tsignal: request.signal,\n\t\t\t\t\t\t\ttimeout: request.timeout,\n\t\t\t\t\t\t\tsize: request.size\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 9\n\t\t\t\t\t\tif (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {\n\t\t\t\t\t\t\treject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));\n\t\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 11\n\t\t\t\t\t\tif (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {\n\t\t\t\t\t\t\trequestOpts.method = 'GET';\n\t\t\t\t\t\t\trequestOpts.body = undefined;\n\t\t\t\t\t\t\trequestOpts.headers.delete('content-length');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 15\n\t\t\t\t\t\tresolve(fetch(new Request(locationURL, requestOpts)));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// prepare response\n\t\t\tres.once('end', function () {\n\t\t\t\tif (signal) signal.removeEventListener('abort', abortAndFinalize);\n\t\t\t});\n\t\t\tlet body = res.pipe(new PassThrough$1());\n\n\t\t\tconst response_options = {\n\t\t\t\turl: request.url,\n\t\t\t\tstatus: res.statusCode,\n\t\t\t\tstatusText: res.statusMessage,\n\t\t\t\theaders: headers,\n\t\t\t\tsize: request.size,\n\t\t\t\ttimeout: request.timeout,\n\t\t\t\tcounter: request.counter\n\t\t\t};\n\n\t\t\t// HTTP-network fetch step 12.1.1.3\n\t\t\tconst codings = headers.get('Content-Encoding');\n\n\t\t\t// HTTP-network fetch step 12.1.1.4: handle content codings\n\n\t\t\t// in following scenarios we ignore compression support\n\t\t\t// 1. compression support is disabled\n\t\t\t// 2. HEAD request\n\t\t\t// 3. no Content-Encoding header\n\t\t\t// 4. no content response (204)\n\t\t\t// 5. content not modified response (304)\n\t\t\tif (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// For Node v6+\n\t\t\t// Be less strict when decoding compressed responses, since sometimes\n\t\t\t// servers send slightly invalid responses that are still accepted\n\t\t\t// by common browsers.\n\t\t\t// Always using Z_SYNC_FLUSH is what cURL does.\n\t\t\tconst zlibOptions = {\n\t\t\t\tflush: zlib.Z_SYNC_FLUSH,\n\t\t\t\tfinishFlush: zlib.Z_SYNC_FLUSH\n\t\t\t};\n\n\t\t\t// for gzip\n\t\t\tif (codings == 'gzip' || codings == 'x-gzip') {\n\t\t\t\tbody = body.pipe(zlib.createGunzip(zlibOptions));\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// for deflate\n\t\t\tif (codings == 'deflate' || codings == 'x-deflate') {\n\t\t\t\t// handle the infamous raw deflate response from old servers\n\t\t\t\t// a hack for old IIS and Apache servers\n\t\t\t\tconst raw = res.pipe(new PassThrough$1());\n\t\t\t\traw.once('data', function (chunk) {\n\t\t\t\t\t// see http://stackoverflow.com/questions/37519828\n\t\t\t\t\tif ((chunk[0] & 0x0F) === 0x08) {\n\t\t\t\t\t\tbody = body.pipe(zlib.createInflate());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbody = body.pipe(zlib.createInflateRaw());\n\t\t\t\t\t}\n\t\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\t\tresolve(response);\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// for br\n\t\t\tif (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') {\n\t\t\t\tbody = body.pipe(zlib.createBrotliDecompress());\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// otherwise, use response as-is\n\t\t\tresponse = new Response(body, response_options);\n\t\t\tresolve(response);\n\t\t});\n\n\t\twriteToStream(req, request);\n\t});\n}\n/**\n * Redirect code matching\n *\n * @param   Number   code  Status code\n * @return  Boolean\n */\nfetch.isRedirect = function (code) {\n\treturn code === 301 || code === 302 || code === 303 || code === 307 || code === 308;\n};\n\n// expose Promise\nfetch.Promise = global.Promise;\n\nmodule.exports = exports = fetch;\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.default = exports;\nexports.Headers = Headers;\nexports.Request = Request;\nexports.Response = Response;\nexports.FetchError = FetchError;\n\n\n/***/ }),\n\n/***/ 1223:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nvar wrappy = __webpack_require__(2940)\nmodule.exports = wrappy(once)\nmodule.exports.strict = wrappy(onceStrict)\n\nonce.proto = once(function () {\n  Object.defineProperty(Function.prototype, 'once', {\n    value: function () {\n      return once(this)\n    },\n    configurable: true\n  })\n\n  Object.defineProperty(Function.prototype, 'onceStrict', {\n    value: function () {\n      return onceStrict(this)\n    },\n    configurable: true\n  })\n})\n\nfunction once (fn) {\n  var f = function () {\n    if (f.called) return f.value\n    f.called = true\n    return f.value = fn.apply(this, arguments)\n  }\n  f.called = false\n  return f\n}\n\nfunction onceStrict (fn) {\n  var f = function () {\n    if (f.called)\n      throw new Error(f.onceError)\n    f.called = true\n    return f.value = fn.apply(this, arguments)\n  }\n  var name = fn.name || 'Function wrapped with `once`'\n  f.onceError = name + \" shouldn't be called more than once\"\n  f.called = false\n  return f\n}\n\n\n/***/ }),\n\n/***/ 4256:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nvar punycode = __webpack_require__(4213);\nvar mappingTable = __webpack_require__(68);\n\nvar PROCESSING_OPTIONS = {\n  TRANSITIONAL: 0,\n  NONTRANSITIONAL: 1\n};\n\nfunction normalize(str) { // fix bug in v8\n  return str.split('\\u0000').map(function (s) { return s.normalize('NFC'); }).join('\\u0000');\n}\n\nfunction findStatus(val) {\n  var start = 0;\n  var end = mappingTable.length - 1;\n\n  while (start <= end) {\n    var mid = Math.floor((start + end) / 2);\n\n    var target = mappingTable[mid];\n    if (target[0][0] <= val && target[0][1] >= val) {\n      return target;\n    } else if (target[0][0] > val) {\n      end = mid - 1;\n    } else {\n      start = mid + 1;\n    }\n  }\n\n  return null;\n}\n\nvar regexAstralSymbols = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\n\nfunction countSymbols(string) {\n  return string\n    // replace every surrogate pair with a BMP symbol\n    .replace(regexAstralSymbols, '_')\n    // then get the length\n    .length;\n}\n\nfunction mapChars(domain_name, useSTD3, processing_option) {\n  var hasError = false;\n  var processed = \"\";\n\n  var len = countSymbols(domain_name);\n  for (var i = 0; i < len; ++i) {\n    var codePoint = domain_name.codePointAt(i);\n    var status = findStatus(codePoint);\n\n    switch (status[1]) {\n      case \"disallowed\":\n        hasError = true;\n        processed += String.fromCodePoint(codePoint);\n        break;\n      case \"ignored\":\n        break;\n      case \"mapped\":\n        processed += String.fromCodePoint.apply(String, status[2]);\n        break;\n      case \"deviation\":\n        if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) {\n          processed += String.fromCodePoint.apply(String, status[2]);\n        } else {\n          processed += String.fromCodePoint(codePoint);\n        }\n        break;\n      case \"valid\":\n        processed += String.fromCodePoint(codePoint);\n        break;\n      case \"disallowed_STD3_mapped\":\n        if (useSTD3) {\n          hasError = true;\n          processed += String.fromCodePoint(codePoint);\n        } else {\n          processed += String.fromCodePoint.apply(String, status[2]);\n        }\n        break;\n      case \"disallowed_STD3_valid\":\n        if (useSTD3) {\n          hasError = true;\n        }\n\n        processed += String.fromCodePoint(codePoint);\n        break;\n    }\n  }\n\n  return {\n    string: processed,\n    error: hasError\n  };\n}\n\nvar combiningMarksRegex = /[\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u08E4-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A01-\\u0A03\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AE2\\u0AE3\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C00-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81-\\u0C83\\u0CBC\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D01-\\u0D03\\u0D3E-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D82\\u0D83\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102B-\\u103E\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F\\u109A-\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B4-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u192B\\u1930-\\u193B\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A17-\\u1A1B\\u1A55-\\u1A5E\\u1A60-\\u1A7C\\u1A7F\\u1AB0-\\u1ABE\\u1B00-\\u1B04\\u1B34-\\u1B44\\u1B6B-\\u1B73\\u1B80-\\u1B82\\u1BA1-\\u1BAD\\u1BE6-\\u1BF3\\u1C24-\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE8\\u1CED\\u1CF2-\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DF5\\u1DFC-\\u1DFF\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA823-\\uA827\\uA880\\uA881\\uA8B4-\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA953\\uA980-\\uA983\\uA9B3-\\uA9C0\\uA9E5\\uAA29-\\uAA36\\uAA43\\uAA4C\\uAA4D\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEB-\\uAAEF\\uAAF5\\uAAF6\\uABE3-\\uABEA\\uABEC\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2D]|\\uD800[\\uDDFD\\uDEE0\\uDF76-\\uDF7A]|\\uD802[\\uDE01-\\uDE03\\uDE05\\uDE06\\uDE0C-\\uDE0F\\uDE38-\\uDE3A\\uDE3F\\uDEE5\\uDEE6]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC46\\uDC7F-\\uDC82\\uDCB0-\\uDCBA\\uDD00-\\uDD02\\uDD27-\\uDD34\\uDD73\\uDD80-\\uDD82\\uDDB3-\\uDDC0\\uDE2C-\\uDE37\\uDEDF-\\uDEEA\\uDF01-\\uDF03\\uDF3C\\uDF3E-\\uDF44\\uDF47\\uDF48\\uDF4B-\\uDF4D\\uDF57\\uDF62\\uDF63\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDCB0-\\uDCC3\\uDDAF-\\uDDB5\\uDDB8-\\uDDC0\\uDE30-\\uDE40\\uDEAB-\\uDEB7]|\\uD81A[\\uDEF0-\\uDEF4\\uDF30-\\uDF36]|\\uD81B[\\uDF51-\\uDF7E\\uDF8F-\\uDF92]|\\uD82F[\\uDC9D\\uDC9E]|\\uD834[\\uDD65-\\uDD69\\uDD6D-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD83A[\\uDCD0-\\uDCD6]|\\uDB40[\\uDD00-\\uDDEF]/;\n\nfunction validateLabel(label, processing_option) {\n  if (label.substr(0, 4) === \"xn--\") {\n    label = punycode.toUnicode(label);\n    processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL;\n  }\n\n  var error = false;\n\n  if (normalize(label) !== label ||\n      (label[3] === \"-\" && label[4] === \"-\") ||\n      label[0] === \"-\" || label[label.length - 1] === \"-\" ||\n      label.indexOf(\".\") !== -1 ||\n      label.search(combiningMarksRegex) === 0) {\n    error = true;\n  }\n\n  var len = countSymbols(label);\n  for (var i = 0; i < len; ++i) {\n    var status = findStatus(label.codePointAt(i));\n    if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== \"valid\") ||\n        (processing === PROCESSING_OPTIONS.NONTRANSITIONAL &&\n         status[1] !== \"valid\" && status[1] !== \"deviation\")) {\n      error = true;\n      break;\n    }\n  }\n\n  return {\n    label: label,\n    error: error\n  };\n}\n\nfunction processing(domain_name, useSTD3, processing_option) {\n  var result = mapChars(domain_name, useSTD3, processing_option);\n  result.string = normalize(result.string);\n\n  var labels = result.string.split(\".\");\n  for (var i = 0; i < labels.length; ++i) {\n    try {\n      var validation = validateLabel(labels[i]);\n      labels[i] = validation.label;\n      result.error = result.error || validation.error;\n    } catch(e) {\n      result.error = true;\n    }\n  }\n\n  return {\n    string: labels.join(\".\"),\n    error: result.error\n  };\n}\n\nmodule.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) {\n  var result = processing(domain_name, useSTD3, processing_option);\n  var labels = result.string.split(\".\");\n  labels = labels.map(function(l) {\n    try {\n      return punycode.toASCII(l);\n    } catch(e) {\n      result.error = true;\n      return l;\n    }\n  });\n\n  if (verifyDnsLength) {\n    var total = labels.slice(0, labels.length - 1).join(\".\").length;\n    if (total.length > 253 || total.length === 0) {\n      result.error = true;\n    }\n\n    for (var i=0; i < labels.length; ++i) {\n      if (labels.length > 63 || labels.length === 0) {\n        result.error = true;\n        break;\n      }\n    }\n  }\n\n  if (result.error) return null;\n  return labels.join(\".\");\n};\n\nmodule.exports.toUnicode = function(domain_name, useSTD3) {\n  var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL);\n\n  return {\n    domain: result.string,\n    error: result.error\n  };\n};\n\nmodule.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS;\n\n\n/***/ }),\n\n/***/ 4294:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nmodule.exports = __webpack_require__(4219);\n\n\n/***/ }),\n\n/***/ 4219:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nvar net = __webpack_require__(1631);\nvar tls = __webpack_require__(4016);\nvar http = __webpack_require__(8605);\nvar https = __webpack_require__(7211);\nvar events = __webpack_require__(8614);\nvar assert = __webpack_require__(2357);\nvar util = __webpack_require__(1669);\n\n\nexports.httpOverHttp = httpOverHttp;\nexports.httpsOverHttp = httpsOverHttp;\nexports.httpOverHttps = httpOverHttps;\nexports.httpsOverHttps = httpsOverHttps;\n\n\nfunction httpOverHttp(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = http.request;\n  return agent;\n}\n\nfunction httpsOverHttp(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = http.request;\n  agent.createSocket = createSecureSocket;\n  agent.defaultPort = 443;\n  return agent;\n}\n\nfunction httpOverHttps(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = https.request;\n  return agent;\n}\n\nfunction httpsOverHttps(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = https.request;\n  agent.createSocket = createSecureSocket;\n  agent.defaultPort = 443;\n  return agent;\n}\n\n\nfunction TunnelingAgent(options) {\n  var self = this;\n  self.options = options || {};\n  self.proxyOptions = self.options.proxy || {};\n  self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;\n  self.requests = [];\n  self.sockets = [];\n\n  self.on('free', function onFree(socket, host, port, localAddress) {\n    var options = toOptions(host, port, localAddress);\n    for (var i = 0, len = self.requests.length; i < len; ++i) {\n      var pending = self.requests[i];\n      if (pending.host === options.host && pending.port === options.port) {\n        // Detect the request to connect same origin server,\n        // reuse the connection.\n        self.requests.splice(i, 1);\n        pending.request.onSocket(socket);\n        return;\n      }\n    }\n    socket.destroy();\n    self.removeSocket(socket);\n  });\n}\nutil.inherits(TunnelingAgent, events.EventEmitter);\n\nTunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {\n  var self = this;\n  var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));\n\n  if (self.sockets.length >= this.maxSockets) {\n    // We are over limit so we'll add it to the queue.\n    self.requests.push(options);\n    return;\n  }\n\n  // If we are under maxSockets create a new one.\n  self.createSocket(options, function(socket) {\n    socket.on('free', onFree);\n    socket.on('close', onCloseOrRemove);\n    socket.on('agentRemove', onCloseOrRemove);\n    req.onSocket(socket);\n\n    function onFree() {\n      self.emit('free', socket, options);\n    }\n\n    function onCloseOrRemove(err) {\n      self.removeSocket(socket);\n      socket.removeListener('free', onFree);\n      socket.removeListener('close', onCloseOrRemove);\n      socket.removeListener('agentRemove', onCloseOrRemove);\n    }\n  });\n};\n\nTunnelingAgent.prototype.createSocket = function createSocket(options, cb) {\n  var self = this;\n  var placeholder = {};\n  self.sockets.push(placeholder);\n\n  var connectOptions = mergeOptions({}, self.proxyOptions, {\n    method: 'CONNECT',\n    path: options.host + ':' + options.port,\n    agent: false,\n    headers: {\n      host: options.host + ':' + options.port\n    }\n  });\n  if (options.localAddress) {\n    connectOptions.localAddress = options.localAddress;\n  }\n  if (connectOptions.proxyAuth) {\n    connectOptions.headers = connectOptions.headers || {};\n    connectOptions.headers['Proxy-Authorization'] = 'Basic ' +\n        new Buffer(connectOptions.proxyAuth).toString('base64');\n  }\n\n  debug('making CONNECT request');\n  var connectReq = self.request(connectOptions);\n  connectReq.useChunkedEncodingByDefault = false; // for v0.6\n  connectReq.once('response', onResponse); // for v0.6\n  connectReq.once('upgrade', onUpgrade);   // for v0.6\n  connectReq.once('connect', onConnect);   // for v0.7 or later\n  connectReq.once('error', onError);\n  connectReq.end();\n\n  function onResponse(res) {\n    // Very hacky. This is necessary to avoid http-parser leaks.\n    res.upgrade = true;\n  }\n\n  function onUpgrade(res, socket, head) {\n    // Hacky.\n    process.nextTick(function() {\n      onConnect(res, socket, head);\n    });\n  }\n\n  function onConnect(res, socket, head) {\n    connectReq.removeAllListeners();\n    socket.removeAllListeners();\n\n    if (res.statusCode !== 200) {\n      debug('tunneling socket could not be established, statusCode=%d',\n        res.statusCode);\n      socket.destroy();\n      var error = new Error('tunneling socket could not be established, ' +\n        'statusCode=' + res.statusCode);\n      error.code = 'ECONNRESET';\n      options.request.emit('error', error);\n      self.removeSocket(placeholder);\n      return;\n    }\n    if (head.length > 0) {\n      debug('got illegal response body from proxy');\n      socket.destroy();\n      var error = new Error('got illegal response body from proxy');\n      error.code = 'ECONNRESET';\n      options.request.emit('error', error);\n      self.removeSocket(placeholder);\n      return;\n    }\n    debug('tunneling connection has established');\n    self.sockets[self.sockets.indexOf(placeholder)] = socket;\n    return cb(socket);\n  }\n\n  function onError(cause) {\n    connectReq.removeAllListeners();\n\n    debug('tunneling socket could not be established, cause=%s\\n',\n          cause.message, cause.stack);\n    var error = new Error('tunneling socket could not be established, ' +\n                          'cause=' + cause.message);\n    error.code = 'ECONNRESET';\n    options.request.emit('error', error);\n    self.removeSocket(placeholder);\n  }\n};\n\nTunnelingAgent.prototype.removeSocket = function removeSocket(socket) {\n  var pos = this.sockets.indexOf(socket)\n  if (pos === -1) {\n    return;\n  }\n  this.sockets.splice(pos, 1);\n\n  var pending = this.requests.shift();\n  if (pending) {\n    // If we have pending requests and a socket gets closed a new one\n    // needs to be created to take over in the pool for the one that closed.\n    this.createSocket(pending, function(socket) {\n      pending.request.onSocket(socket);\n    });\n  }\n};\n\nfunction createSecureSocket(options, cb) {\n  var self = this;\n  TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {\n    var hostHeader = options.request.getHeader('host');\n    var tlsOptions = mergeOptions({}, self.options, {\n      socket: socket,\n      servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host\n    });\n\n    // 0 is dummy port for v0.6\n    var secureSocket = tls.connect(0, tlsOptions);\n    self.sockets[self.sockets.indexOf(socket)] = secureSocket;\n    cb(secureSocket);\n  });\n}\n\n\nfunction toOptions(host, port, localAddress) {\n  if (typeof host === 'string') { // since v0.10\n    return {\n      host: host,\n      port: port,\n      localAddress: localAddress\n    };\n  }\n  return host; // for v0.11 or later\n}\n\nfunction mergeOptions(target) {\n  for (var i = 1, len = arguments.length; i < len; ++i) {\n    var overrides = arguments[i];\n    if (typeof overrides === 'object') {\n      var keys = Object.keys(overrides);\n      for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {\n        var k = keys[j];\n        if (overrides[k] !== undefined) {\n          target[k] = overrides[k];\n        }\n      }\n    }\n  }\n  return target;\n}\n\n\nvar debug;\nif (process.env.NODE_DEBUG && /\\btunnel\\b/.test(process.env.NODE_DEBUG)) {\n  debug = function() {\n    var args = Array.prototype.slice.call(arguments);\n    if (typeof args[0] === 'string') {\n      args[0] = 'TUNNEL: ' + args[0];\n    } else {\n      args.unshift('TUNNEL:');\n    }\n    console.error.apply(console, args);\n  }\n} else {\n  debug = function() {};\n}\nexports.debug = debug; // for test\n\n\n/***/ }),\n\n/***/ 5030:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction getUserAgent() {\n  if (typeof navigator === \"object\" && \"userAgent\" in navigator) {\n    return navigator.userAgent;\n  }\n\n  if (typeof process === \"object\" && \"version\" in process) {\n    return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`;\n  }\n\n  return \"<environment undetectable>\";\n}\n\nexports.getUserAgent = getUserAgent;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 4886:\n/***/ ((module) => {\n\n\"use strict\";\n\n\nvar conversions = {};\nmodule.exports = conversions;\n\nfunction sign(x) {\n    return x < 0 ? -1 : 1;\n}\n\nfunction evenRound(x) {\n    // Round x to the nearest integer, choosing the even integer if it lies halfway between two.\n    if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor)\n        return Math.floor(x);\n    } else {\n        return Math.round(x);\n    }\n}\n\nfunction createNumberConversion(bitLength, typeOpts) {\n    if (!typeOpts.unsigned) {\n        --bitLength;\n    }\n    const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength);\n    const upperBound = Math.pow(2, bitLength) - 1;\n\n    const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength);\n    const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1);\n\n    return function(V, opts) {\n        if (!opts) opts = {};\n\n        let x = +V;\n\n        if (opts.enforceRange) {\n            if (!Number.isFinite(x)) {\n                throw new TypeError(\"Argument is not a finite number\");\n            }\n\n            x = sign(x) * Math.floor(Math.abs(x));\n            if (x < lowerBound || x > upperBound) {\n                throw new TypeError(\"Argument is not in byte range\");\n            }\n\n            return x;\n        }\n\n        if (!isNaN(x) && opts.clamp) {\n            x = evenRound(x);\n\n            if (x < lowerBound) x = lowerBound;\n            if (x > upperBound) x = upperBound;\n            return x;\n        }\n\n        if (!Number.isFinite(x) || x === 0) {\n            return 0;\n        }\n\n        x = sign(x) * Math.floor(Math.abs(x));\n        x = x % moduloVal;\n\n        if (!typeOpts.unsigned && x >= moduloBound) {\n            return x - moduloVal;\n        } else if (typeOpts.unsigned) {\n            if (x < 0) {\n              x += moduloVal;\n            } else if (x === -0) { // don't return negative zero\n              return 0;\n            }\n        }\n\n        return x;\n    }\n}\n\nconversions[\"void\"] = function () {\n    return undefined;\n};\n\nconversions[\"boolean\"] = function (val) {\n    return !!val;\n};\n\nconversions[\"byte\"] = createNumberConversion(8, { unsigned: false });\nconversions[\"octet\"] = createNumberConversion(8, { unsigned: true });\n\nconversions[\"short\"] = createNumberConversion(16, { unsigned: false });\nconversions[\"unsigned short\"] = createNumberConversion(16, { unsigned: true });\n\nconversions[\"long\"] = createNumberConversion(32, { unsigned: false });\nconversions[\"unsigned long\"] = createNumberConversion(32, { unsigned: true });\n\nconversions[\"long long\"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 });\nconversions[\"unsigned long long\"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 });\n\nconversions[\"double\"] = function (V) {\n    const x = +V;\n\n    if (!Number.isFinite(x)) {\n        throw new TypeError(\"Argument is not a finite floating-point value\");\n    }\n\n    return x;\n};\n\nconversions[\"unrestricted double\"] = function (V) {\n    const x = +V;\n\n    if (isNaN(x)) {\n        throw new TypeError(\"Argument is NaN\");\n    }\n\n    return x;\n};\n\n// not quite valid, but good enough for JS\nconversions[\"float\"] = conversions[\"double\"];\nconversions[\"unrestricted float\"] = conversions[\"unrestricted double\"];\n\nconversions[\"DOMString\"] = function (V, opts) {\n    if (!opts) opts = {};\n\n    if (opts.treatNullAsEmptyString && V === null) {\n        return \"\";\n    }\n\n    return String(V);\n};\n\nconversions[\"ByteString\"] = function (V, opts) {\n    const x = String(V);\n    let c = undefined;\n    for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) {\n        if (c > 255) {\n            throw new TypeError(\"Argument is not a valid bytestring\");\n        }\n    }\n\n    return x;\n};\n\nconversions[\"USVString\"] = function (V) {\n    const S = String(V);\n    const n = S.length;\n    const U = [];\n    for (let i = 0; i < n; ++i) {\n        const c = S.charCodeAt(i);\n        if (c < 0xD800 || c > 0xDFFF) {\n            U.push(String.fromCodePoint(c));\n        } else if (0xDC00 <= c && c <= 0xDFFF) {\n            U.push(String.fromCodePoint(0xFFFD));\n        } else {\n            if (i === n - 1) {\n                U.push(String.fromCodePoint(0xFFFD));\n            } else {\n                const d = S.charCodeAt(i + 1);\n                if (0xDC00 <= d && d <= 0xDFFF) {\n                    const a = c & 0x3FF;\n                    const b = d & 0x3FF;\n                    U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b));\n                    ++i;\n                } else {\n                    U.push(String.fromCodePoint(0xFFFD));\n                }\n            }\n        }\n    }\n\n    return U.join('');\n};\n\nconversions[\"Date\"] = function (V, opts) {\n    if (!(V instanceof Date)) {\n        throw new TypeError(\"Argument is not a Date object\");\n    }\n    if (isNaN(V)) {\n        return undefined;\n    }\n\n    return V;\n};\n\nconversions[\"RegExp\"] = function (V, opts) {\n    if (!(V instanceof RegExp)) {\n        V = new RegExp(V);\n    }\n\n    return V;\n};\n\n\n/***/ }),\n\n/***/ 7537:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nconst usm = __webpack_require__(2158);\n\nexports.implementation = class URLImpl {\n  constructor(constructorArgs) {\n    const url = constructorArgs[0];\n    const base = constructorArgs[1];\n\n    let parsedBase = null;\n    if (base !== undefined) {\n      parsedBase = usm.basicURLParse(base);\n      if (parsedBase === \"failure\") {\n        throw new TypeError(\"Invalid base URL\");\n      }\n    }\n\n    const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase });\n    if (parsedURL === \"failure\") {\n      throw new TypeError(\"Invalid URL\");\n    }\n\n    this._url = parsedURL;\n\n    // TODO: query stuff\n  }\n\n  get href() {\n    return usm.serializeURL(this._url);\n  }\n\n  set href(v) {\n    const parsedURL = usm.basicURLParse(v);\n    if (parsedURL === \"failure\") {\n      throw new TypeError(\"Invalid URL\");\n    }\n\n    this._url = parsedURL;\n  }\n\n  get origin() {\n    return usm.serializeURLOrigin(this._url);\n  }\n\n  get protocol() {\n    return this._url.scheme + \":\";\n  }\n\n  set protocol(v) {\n    usm.basicURLParse(v + \":\", { url: this._url, stateOverride: \"scheme start\" });\n  }\n\n  get username() {\n    return this._url.username;\n  }\n\n  set username(v) {\n    if (usm.cannotHaveAUsernamePasswordPort(this._url)) {\n      return;\n    }\n\n    usm.setTheUsername(this._url, v);\n  }\n\n  get password() {\n    return this._url.password;\n  }\n\n  set password(v) {\n    if (usm.cannotHaveAUsernamePasswordPort(this._url)) {\n      return;\n    }\n\n    usm.setThePassword(this._url, v);\n  }\n\n  get host() {\n    const url = this._url;\n\n    if (url.host === null) {\n      return \"\";\n    }\n\n    if (url.port === null) {\n      return usm.serializeHost(url.host);\n    }\n\n    return usm.serializeHost(url.host) + \":\" + usm.serializeInteger(url.port);\n  }\n\n  set host(v) {\n    if (this._url.cannotBeABaseURL) {\n      return;\n    }\n\n    usm.basicURLParse(v, { url: this._url, stateOverride: \"host\" });\n  }\n\n  get hostname() {\n    if (this._url.host === null) {\n      return \"\";\n    }\n\n    return usm.serializeHost(this._url.host);\n  }\n\n  set hostname(v) {\n    if (this._url.cannotBeABaseURL) {\n      return;\n    }\n\n    usm.basicURLParse(v, { url: this._url, stateOverride: \"hostname\" });\n  }\n\n  get port() {\n    if (this._url.port === null) {\n      return \"\";\n    }\n\n    return usm.serializeInteger(this._url.port);\n  }\n\n  set port(v) {\n    if (usm.cannotHaveAUsernamePasswordPort(this._url)) {\n      return;\n    }\n\n    if (v === \"\") {\n      this._url.port = null;\n    } else {\n      usm.basicURLParse(v, { url: this._url, stateOverride: \"port\" });\n    }\n  }\n\n  get pathname() {\n    if (this._url.cannotBeABaseURL) {\n      return this._url.path[0];\n    }\n\n    if (this._url.path.length === 0) {\n      return \"\";\n    }\n\n    return \"/\" + this._url.path.join(\"/\");\n  }\n\n  set pathname(v) {\n    if (this._url.cannotBeABaseURL) {\n      return;\n    }\n\n    this._url.path = [];\n    usm.basicURLParse(v, { url: this._url, stateOverride: \"path start\" });\n  }\n\n  get search() {\n    if (this._url.query === null || this._url.query === \"\") {\n      return \"\";\n    }\n\n    return \"?\" + this._url.query;\n  }\n\n  set search(v) {\n    // TODO: query stuff\n\n    const url = this._url;\n\n    if (v === \"\") {\n      url.query = null;\n      return;\n    }\n\n    const input = v[0] === \"?\" ? v.substring(1) : v;\n    url.query = \"\";\n    usm.basicURLParse(input, { url, stateOverride: \"query\" });\n  }\n\n  get hash() {\n    if (this._url.fragment === null || this._url.fragment === \"\") {\n      return \"\";\n    }\n\n    return \"#\" + this._url.fragment;\n  }\n\n  set hash(v) {\n    if (v === \"\") {\n      this._url.fragment = null;\n      return;\n    }\n\n    const input = v[0] === \"#\" ? v.substring(1) : v;\n    this._url.fragment = \"\";\n    usm.basicURLParse(input, { url: this._url, stateOverride: \"fragment\" });\n  }\n\n  toJSON() {\n    return this.href;\n  }\n};\n\n\n/***/ }),\n\n/***/ 3394:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nconst conversions = __webpack_require__(4886);\nconst utils = __webpack_require__(3185);\nconst Impl = __webpack_require__(7537);\n\nconst impl = utils.implSymbol;\n\nfunction URL(url) {\n  if (!this || this[impl] || !(this instanceof URL)) {\n    throw new TypeError(\"Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function.\");\n  }\n  if (arguments.length < 1) {\n    throw new TypeError(\"Failed to construct 'URL': 1 argument required, but only \" + arguments.length + \" present.\");\n  }\n  const args = [];\n  for (let i = 0; i < arguments.length && i < 2; ++i) {\n    args[i] = arguments[i];\n  }\n  args[0] = conversions[\"USVString\"](args[0]);\n  if (args[1] !== undefined) {\n  args[1] = conversions[\"USVString\"](args[1]);\n  }\n\n  module.exports.setup(this, args);\n}\n\nURL.prototype.toJSON = function toJSON() {\n  if (!this || !module.exports.is(this)) {\n    throw new TypeError(\"Illegal invocation\");\n  }\n  const args = [];\n  for (let i = 0; i < arguments.length && i < 0; ++i) {\n    args[i] = arguments[i];\n  }\n  return this[impl].toJSON.apply(this[impl], args);\n};\nObject.defineProperty(URL.prototype, \"href\", {\n  get() {\n    return this[impl].href;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].href = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nURL.prototype.toString = function () {\n  if (!this || !module.exports.is(this)) {\n    throw new TypeError(\"Illegal invocation\");\n  }\n  return this.href;\n};\n\nObject.defineProperty(URL.prototype, \"origin\", {\n  get() {\n    return this[impl].origin;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"protocol\", {\n  get() {\n    return this[impl].protocol;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].protocol = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"username\", {\n  get() {\n    return this[impl].username;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].username = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"password\", {\n  get() {\n    return this[impl].password;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].password = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"host\", {\n  get() {\n    return this[impl].host;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].host = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"hostname\", {\n  get() {\n    return this[impl].hostname;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].hostname = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"port\", {\n  get() {\n    return this[impl].port;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].port = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"pathname\", {\n  get() {\n    return this[impl].pathname;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].pathname = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"search\", {\n  get() {\n    return this[impl].search;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].search = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"hash\", {\n  get() {\n    return this[impl].hash;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].hash = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\n\nmodule.exports = {\n  is(obj) {\n    return !!obj && obj[impl] instanceof Impl.implementation;\n  },\n  create(constructorArgs, privateData) {\n    let obj = Object.create(URL.prototype);\n    this.setup(obj, constructorArgs, privateData);\n    return obj;\n  },\n  setup(obj, constructorArgs, privateData) {\n    if (!privateData) privateData = {};\n    privateData.wrapper = obj;\n\n    obj[impl] = new Impl.implementation(constructorArgs, privateData);\n    obj[impl][utils.wrapperSymbol] = obj;\n  },\n  interface: URL,\n  expose: {\n    Window: { URL: URL },\n    Worker: { URL: URL }\n  }\n};\n\n\n\n/***/ }),\n\n/***/ 8665:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nexports.URL = __webpack_require__(3394).interface;\nexports.serializeURL = __webpack_require__(2158).serializeURL;\nexports.serializeURLOrigin = __webpack_require__(2158).serializeURLOrigin;\nexports.basicURLParse = __webpack_require__(2158).basicURLParse;\nexports.setTheUsername = __webpack_require__(2158).setTheUsername;\nexports.setThePassword = __webpack_require__(2158).setThePassword;\nexports.serializeHost = __webpack_require__(2158).serializeHost;\nexports.serializeInteger = __webpack_require__(2158).serializeInteger;\nexports.parseURL = __webpack_require__(2158).parseURL;\n\n\n/***/ }),\n\n/***/ 2158:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\"use strict\";\n\r\nconst punycode = __webpack_require__(4213);\r\nconst tr46 = __webpack_require__(4256);\r\n\r\nconst specialSchemes = {\r\n  ftp: 21,\r\n  file: null,\r\n  gopher: 70,\r\n  http: 80,\r\n  https: 443,\r\n  ws: 80,\r\n  wss: 443\r\n};\r\n\r\nconst failure = Symbol(\"failure\");\r\n\r\nfunction countSymbols(str) {\r\n  return punycode.ucs2.decode(str).length;\r\n}\r\n\r\nfunction at(input, idx) {\r\n  const c = input[idx];\r\n  return isNaN(c) ? undefined : String.fromCodePoint(c);\r\n}\r\n\r\nfunction isASCIIDigit(c) {\r\n  return c >= 0x30 && c <= 0x39;\r\n}\r\n\r\nfunction isASCIIAlpha(c) {\r\n  return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A);\r\n}\r\n\r\nfunction isASCIIAlphanumeric(c) {\r\n  return isASCIIAlpha(c) || isASCIIDigit(c);\r\n}\r\n\r\nfunction isASCIIHex(c) {\r\n  return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66);\r\n}\r\n\r\nfunction isSingleDot(buffer) {\r\n  return buffer === \".\" || buffer.toLowerCase() === \"%2e\";\r\n}\r\n\r\nfunction isDoubleDot(buffer) {\r\n  buffer = buffer.toLowerCase();\r\n  return buffer === \"..\" || buffer === \"%2e.\" || buffer === \".%2e\" || buffer === \"%2e%2e\";\r\n}\r\n\r\nfunction isWindowsDriveLetterCodePoints(cp1, cp2) {\r\n  return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124);\r\n}\r\n\r\nfunction isWindowsDriveLetterString(string) {\r\n  return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === \":\" || string[1] === \"|\");\r\n}\r\n\r\nfunction isNormalizedWindowsDriveLetterString(string) {\r\n  return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === \":\";\r\n}\r\n\r\nfunction containsForbiddenHostCodePoint(string) {\r\n  return string.search(/\\u0000|\\u0009|\\u000A|\\u000D|\\u0020|#|%|\\/|:|\\?|@|\\[|\\\\|\\]/) !== -1;\r\n}\r\n\r\nfunction containsForbiddenHostCodePointExcludingPercent(string) {\r\n  return string.search(/\\u0000|\\u0009|\\u000A|\\u000D|\\u0020|#|\\/|:|\\?|@|\\[|\\\\|\\]/) !== -1;\r\n}\r\n\r\nfunction isSpecialScheme(scheme) {\r\n  return specialSchemes[scheme] !== undefined;\r\n}\r\n\r\nfunction isSpecial(url) {\r\n  return isSpecialScheme(url.scheme);\r\n}\r\n\r\nfunction defaultPort(scheme) {\r\n  return specialSchemes[scheme];\r\n}\r\n\r\nfunction percentEncode(c) {\r\n  let hex = c.toString(16).toUpperCase();\r\n  if (hex.length === 1) {\r\n    hex = \"0\" + hex;\r\n  }\r\n\r\n  return \"%\" + hex;\r\n}\r\n\r\nfunction utf8PercentEncode(c) {\r\n  const buf = new Buffer(c);\r\n\r\n  let str = \"\";\r\n\r\n  for (let i = 0; i < buf.length; ++i) {\r\n    str += percentEncode(buf[i]);\r\n  }\r\n\r\n  return str;\r\n}\r\n\r\nfunction utf8PercentDecode(str) {\r\n  const input = new Buffer(str);\r\n  const output = [];\r\n  for (let i = 0; i < input.length; ++i) {\r\n    if (input[i] !== 37) {\r\n      output.push(input[i]);\r\n    } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) {\r\n      output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16));\r\n      i += 2;\r\n    } else {\r\n      output.push(input[i]);\r\n    }\r\n  }\r\n  return new Buffer(output).toString();\r\n}\r\n\r\nfunction isC0ControlPercentEncode(c) {\r\n  return c <= 0x1F || c > 0x7E;\r\n}\r\n\r\nconst extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]);\r\nfunction isPathPercentEncode(c) {\r\n  return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c);\r\n}\r\n\r\nconst extraUserinfoPercentEncodeSet =\r\n  new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]);\r\nfunction isUserinfoPercentEncode(c) {\r\n  return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c);\r\n}\r\n\r\nfunction percentEncodeChar(c, encodeSetPredicate) {\r\n  const cStr = String.fromCodePoint(c);\r\n\r\n  if (encodeSetPredicate(c)) {\r\n    return utf8PercentEncode(cStr);\r\n  }\r\n\r\n  return cStr;\r\n}\r\n\r\nfunction parseIPv4Number(input) {\r\n  let R = 10;\r\n\r\n  if (input.length >= 2 && input.charAt(0) === \"0\" && input.charAt(1).toLowerCase() === \"x\") {\r\n    input = input.substring(2);\r\n    R = 16;\r\n  } else if (input.length >= 2 && input.charAt(0) === \"0\") {\r\n    input = input.substring(1);\r\n    R = 8;\r\n  }\r\n\r\n  if (input === \"\") {\r\n    return 0;\r\n  }\r\n\r\n  const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/);\r\n  if (regex.test(input)) {\r\n    return failure;\r\n  }\r\n\r\n  return parseInt(input, R);\r\n}\r\n\r\nfunction parseIPv4(input) {\r\n  const parts = input.split(\".\");\r\n  if (parts[parts.length - 1] === \"\") {\r\n    if (parts.length > 1) {\r\n      parts.pop();\r\n    }\r\n  }\r\n\r\n  if (parts.length > 4) {\r\n    return input;\r\n  }\r\n\r\n  const numbers = [];\r\n  for (const part of parts) {\r\n    if (part === \"\") {\r\n      return input;\r\n    }\r\n    const n = parseIPv4Number(part);\r\n    if (n === failure) {\r\n      return input;\r\n    }\r\n\r\n    numbers.push(n);\r\n  }\r\n\r\n  for (let i = 0; i < numbers.length - 1; ++i) {\r\n    if (numbers[i] > 255) {\r\n      return failure;\r\n    }\r\n  }\r\n  if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) {\r\n    return failure;\r\n  }\r\n\r\n  let ipv4 = numbers.pop();\r\n  let counter = 0;\r\n\r\n  for (const n of numbers) {\r\n    ipv4 += n * Math.pow(256, 3 - counter);\r\n    ++counter;\r\n  }\r\n\r\n  return ipv4;\r\n}\r\n\r\nfunction serializeIPv4(address) {\r\n  let output = \"\";\r\n  let n = address;\r\n\r\n  for (let i = 1; i <= 4; ++i) {\r\n    output = String(n % 256) + output;\r\n    if (i !== 4) {\r\n      output = \".\" + output;\r\n    }\r\n    n = Math.floor(n / 256);\r\n  }\r\n\r\n  return output;\r\n}\r\n\r\nfunction parseIPv6(input) {\r\n  const address = [0, 0, 0, 0, 0, 0, 0, 0];\r\n  let pieceIndex = 0;\r\n  let compress = null;\r\n  let pointer = 0;\r\n\r\n  input = punycode.ucs2.decode(input);\r\n\r\n  if (input[pointer] === 58) {\r\n    if (input[pointer + 1] !== 58) {\r\n      return failure;\r\n    }\r\n\r\n    pointer += 2;\r\n    ++pieceIndex;\r\n    compress = pieceIndex;\r\n  }\r\n\r\n  while (pointer < input.length) {\r\n    if (pieceIndex === 8) {\r\n      return failure;\r\n    }\r\n\r\n    if (input[pointer] === 58) {\r\n      if (compress !== null) {\r\n        return failure;\r\n      }\r\n      ++pointer;\r\n      ++pieceIndex;\r\n      compress = pieceIndex;\r\n      continue;\r\n    }\r\n\r\n    let value = 0;\r\n    let length = 0;\r\n\r\n    while (length < 4 && isASCIIHex(input[pointer])) {\r\n      value = value * 0x10 + parseInt(at(input, pointer), 16);\r\n      ++pointer;\r\n      ++length;\r\n    }\r\n\r\n    if (input[pointer] === 46) {\r\n      if (length === 0) {\r\n        return failure;\r\n      }\r\n\r\n      pointer -= length;\r\n\r\n      if (pieceIndex > 6) {\r\n        return failure;\r\n      }\r\n\r\n      let numbersSeen = 0;\r\n\r\n      while (input[pointer] !== undefined) {\r\n        let ipv4Piece = null;\r\n\r\n        if (numbersSeen > 0) {\r\n          if (input[pointer] === 46 && numbersSeen < 4) {\r\n            ++pointer;\r\n          } else {\r\n            return failure;\r\n          }\r\n        }\r\n\r\n        if (!isASCIIDigit(input[pointer])) {\r\n          return failure;\r\n        }\r\n\r\n        while (isASCIIDigit(input[pointer])) {\r\n          const number = parseInt(at(input, pointer));\r\n          if (ipv4Piece === null) {\r\n            ipv4Piece = number;\r\n          } else if (ipv4Piece === 0) {\r\n            return failure;\r\n          } else {\r\n            ipv4Piece = ipv4Piece * 10 + number;\r\n          }\r\n          if (ipv4Piece > 255) {\r\n            return failure;\r\n          }\r\n          ++pointer;\r\n        }\r\n\r\n        address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece;\r\n\r\n        ++numbersSeen;\r\n\r\n        if (numbersSeen === 2 || numbersSeen === 4) {\r\n          ++pieceIndex;\r\n        }\r\n      }\r\n\r\n      if (numbersSeen !== 4) {\r\n        return failure;\r\n      }\r\n\r\n      break;\r\n    } else if (input[pointer] === 58) {\r\n      ++pointer;\r\n      if (input[pointer] === undefined) {\r\n        return failure;\r\n      }\r\n    } else if (input[pointer] !== undefined) {\r\n      return failure;\r\n    }\r\n\r\n    address[pieceIndex] = value;\r\n    ++pieceIndex;\r\n  }\r\n\r\n  if (compress !== null) {\r\n    let swaps = pieceIndex - compress;\r\n    pieceIndex = 7;\r\n    while (pieceIndex !== 0 && swaps > 0) {\r\n      const temp = address[compress + swaps - 1];\r\n      address[compress + swaps - 1] = address[pieceIndex];\r\n      address[pieceIndex] = temp;\r\n      --pieceIndex;\r\n      --swaps;\r\n    }\r\n  } else if (compress === null && pieceIndex !== 8) {\r\n    return failure;\r\n  }\r\n\r\n  return address;\r\n}\r\n\r\nfunction serializeIPv6(address) {\r\n  let output = \"\";\r\n  const seqResult = findLongestZeroSequence(address);\r\n  const compress = seqResult.idx;\r\n  let ignore0 = false;\r\n\r\n  for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) {\r\n    if (ignore0 && address[pieceIndex] === 0) {\r\n      continue;\r\n    } else if (ignore0) {\r\n      ignore0 = false;\r\n    }\r\n\r\n    if (compress === pieceIndex) {\r\n      const separator = pieceIndex === 0 ? \"::\" : \":\";\r\n      output += separator;\r\n      ignore0 = true;\r\n      continue;\r\n    }\r\n\r\n    output += address[pieceIndex].toString(16);\r\n\r\n    if (pieceIndex !== 7) {\r\n      output += \":\";\r\n    }\r\n  }\r\n\r\n  return output;\r\n}\r\n\r\nfunction parseHost(input, isSpecialArg) {\r\n  if (input[0] === \"[\") {\r\n    if (input[input.length - 1] !== \"]\") {\r\n      return failure;\r\n    }\r\n\r\n    return parseIPv6(input.substring(1, input.length - 1));\r\n  }\r\n\r\n  if (!isSpecialArg) {\r\n    return parseOpaqueHost(input);\r\n  }\r\n\r\n  const domain = utf8PercentDecode(input);\r\n  const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false);\r\n  if (asciiDomain === null) {\r\n    return failure;\r\n  }\r\n\r\n  if (containsForbiddenHostCodePoint(asciiDomain)) {\r\n    return failure;\r\n  }\r\n\r\n  const ipv4Host = parseIPv4(asciiDomain);\r\n  if (typeof ipv4Host === \"number\" || ipv4Host === failure) {\r\n    return ipv4Host;\r\n  }\r\n\r\n  return asciiDomain;\r\n}\r\n\r\nfunction parseOpaqueHost(input) {\r\n  if (containsForbiddenHostCodePointExcludingPercent(input)) {\r\n    return failure;\r\n  }\r\n\r\n  let output = \"\";\r\n  const decoded = punycode.ucs2.decode(input);\r\n  for (let i = 0; i < decoded.length; ++i) {\r\n    output += percentEncodeChar(decoded[i], isC0ControlPercentEncode);\r\n  }\r\n  return output;\r\n}\r\n\r\nfunction findLongestZeroSequence(arr) {\r\n  let maxIdx = null;\r\n  let maxLen = 1; // only find elements > 1\r\n  let currStart = null;\r\n  let currLen = 0;\r\n\r\n  for (let i = 0; i < arr.length; ++i) {\r\n    if (arr[i] !== 0) {\r\n      if (currLen > maxLen) {\r\n        maxIdx = currStart;\r\n        maxLen = currLen;\r\n      }\r\n\r\n      currStart = null;\r\n      currLen = 0;\r\n    } else {\r\n      if (currStart === null) {\r\n        currStart = i;\r\n      }\r\n      ++currLen;\r\n    }\r\n  }\r\n\r\n  // if trailing zeros\r\n  if (currLen > maxLen) {\r\n    maxIdx = currStart;\r\n    maxLen = currLen;\r\n  }\r\n\r\n  return {\r\n    idx: maxIdx,\r\n    len: maxLen\r\n  };\r\n}\r\n\r\nfunction serializeHost(host) {\r\n  if (typeof host === \"number\") {\r\n    return serializeIPv4(host);\r\n  }\r\n\r\n  // IPv6 serializer\r\n  if (host instanceof Array) {\r\n    return \"[\" + serializeIPv6(host) + \"]\";\r\n  }\r\n\r\n  return host;\r\n}\r\n\r\nfunction trimControlChars(url) {\r\n  return url.replace(/^[\\u0000-\\u001F\\u0020]+|[\\u0000-\\u001F\\u0020]+$/g, \"\");\r\n}\r\n\r\nfunction trimTabAndNewline(url) {\r\n  return url.replace(/\\u0009|\\u000A|\\u000D/g, \"\");\r\n}\r\n\r\nfunction shortenPath(url) {\r\n  const path = url.path;\r\n  if (path.length === 0) {\r\n    return;\r\n  }\r\n  if (url.scheme === \"file\" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) {\r\n    return;\r\n  }\r\n\r\n  path.pop();\r\n}\r\n\r\nfunction includesCredentials(url) {\r\n  return url.username !== \"\" || url.password !== \"\";\r\n}\r\n\r\nfunction cannotHaveAUsernamePasswordPort(url) {\r\n  return url.host === null || url.host === \"\" || url.cannotBeABaseURL || url.scheme === \"file\";\r\n}\r\n\r\nfunction isNormalizedWindowsDriveLetter(string) {\r\n  return /^[A-Za-z]:$/.test(string);\r\n}\r\n\r\nfunction URLStateMachine(input, base, encodingOverride, url, stateOverride) {\r\n  this.pointer = 0;\r\n  this.input = input;\r\n  this.base = base || null;\r\n  this.encodingOverride = encodingOverride || \"utf-8\";\r\n  this.stateOverride = stateOverride;\r\n  this.url = url;\r\n  this.failure = false;\r\n  this.parseError = false;\r\n\r\n  if (!this.url) {\r\n    this.url = {\r\n      scheme: \"\",\r\n      username: \"\",\r\n      password: \"\",\r\n      host: null,\r\n      port: null,\r\n      path: [],\r\n      query: null,\r\n      fragment: null,\r\n\r\n      cannotBeABaseURL: false\r\n    };\r\n\r\n    const res = trimControlChars(this.input);\r\n    if (res !== this.input) {\r\n      this.parseError = true;\r\n    }\r\n    this.input = res;\r\n  }\r\n\r\n  const res = trimTabAndNewline(this.input);\r\n  if (res !== this.input) {\r\n    this.parseError = true;\r\n  }\r\n  this.input = res;\r\n\r\n  this.state = stateOverride || \"scheme start\";\r\n\r\n  this.buffer = \"\";\r\n  this.atFlag = false;\r\n  this.arrFlag = false;\r\n  this.passwordTokenSeenFlag = false;\r\n\r\n  this.input = punycode.ucs2.decode(this.input);\r\n\r\n  for (; this.pointer <= this.input.length; ++this.pointer) {\r\n    const c = this.input[this.pointer];\r\n    const cStr = isNaN(c) ? undefined : String.fromCodePoint(c);\r\n\r\n    // exec state machine\r\n    const ret = this[\"parse \" + this.state](c, cStr);\r\n    if (!ret) {\r\n      break; // terminate algorithm\r\n    } else if (ret === failure) {\r\n      this.failure = true;\r\n      break;\r\n    }\r\n  }\r\n}\r\n\r\nURLStateMachine.prototype[\"parse scheme start\"] = function parseSchemeStart(c, cStr) {\r\n  if (isASCIIAlpha(c)) {\r\n    this.buffer += cStr.toLowerCase();\r\n    this.state = \"scheme\";\r\n  } else if (!this.stateOverride) {\r\n    this.state = \"no scheme\";\r\n    --this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n    return failure;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse scheme\"] = function parseScheme(c, cStr) {\r\n  if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) {\r\n    this.buffer += cStr.toLowerCase();\r\n  } else if (c === 58) {\r\n    if (this.stateOverride) {\r\n      if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) {\r\n        return false;\r\n      }\r\n\r\n      if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) {\r\n        return false;\r\n      }\r\n\r\n      if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === \"file\") {\r\n        return false;\r\n      }\r\n\r\n      if (this.url.scheme === \"file\" && (this.url.host === \"\" || this.url.host === null)) {\r\n        return false;\r\n      }\r\n    }\r\n    this.url.scheme = this.buffer;\r\n    this.buffer = \"\";\r\n    if (this.stateOverride) {\r\n      return false;\r\n    }\r\n    if (this.url.scheme === \"file\") {\r\n      if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) {\r\n        this.parseError = true;\r\n      }\r\n      this.state = \"file\";\r\n    } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) {\r\n      this.state = \"special relative or authority\";\r\n    } else if (isSpecial(this.url)) {\r\n      this.state = \"special authority slashes\";\r\n    } else if (this.input[this.pointer + 1] === 47) {\r\n      this.state = \"path or authority\";\r\n      ++this.pointer;\r\n    } else {\r\n      this.url.cannotBeABaseURL = true;\r\n      this.url.path.push(\"\");\r\n      this.state = \"cannot-be-a-base-URL path\";\r\n    }\r\n  } else if (!this.stateOverride) {\r\n    this.buffer = \"\";\r\n    this.state = \"no scheme\";\r\n    this.pointer = -1;\r\n  } else {\r\n    this.parseError = true;\r\n    return failure;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse no scheme\"] = function parseNoScheme(c) {\r\n  if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) {\r\n    return failure;\r\n  } else if (this.base.cannotBeABaseURL && c === 35) {\r\n    this.url.scheme = this.base.scheme;\r\n    this.url.path = this.base.path.slice();\r\n    this.url.query = this.base.query;\r\n    this.url.fragment = \"\";\r\n    this.url.cannotBeABaseURL = true;\r\n    this.state = \"fragment\";\r\n  } else if (this.base.scheme === \"file\") {\r\n    this.state = \"file\";\r\n    --this.pointer;\r\n  } else {\r\n    this.state = \"relative\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse special relative or authority\"] = function parseSpecialRelativeOrAuthority(c) {\r\n  if (c === 47 && this.input[this.pointer + 1] === 47) {\r\n    this.state = \"special authority ignore slashes\";\r\n    ++this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n    this.state = \"relative\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse path or authority\"] = function parsePathOrAuthority(c) {\r\n  if (c === 47) {\r\n    this.state = \"authority\";\r\n  } else {\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse relative\"] = function parseRelative(c) {\r\n  this.url.scheme = this.base.scheme;\r\n  if (isNaN(c)) {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.url.path = this.base.path.slice();\r\n    this.url.query = this.base.query;\r\n  } else if (c === 47) {\r\n    this.state = \"relative slash\";\r\n  } else if (c === 63) {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.url.path = this.base.path.slice();\r\n    this.url.query = \"\";\r\n    this.state = \"query\";\r\n  } else if (c === 35) {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.url.path = this.base.path.slice();\r\n    this.url.query = this.base.query;\r\n    this.url.fragment = \"\";\r\n    this.state = \"fragment\";\r\n  } else if (isSpecial(this.url) && c === 92) {\r\n    this.parseError = true;\r\n    this.state = \"relative slash\";\r\n  } else {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.url.path = this.base.path.slice(0, this.base.path.length - 1);\r\n\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse relative slash\"] = function parseRelativeSlash(c) {\r\n  if (isSpecial(this.url) && (c === 47 || c === 92)) {\r\n    if (c === 92) {\r\n      this.parseError = true;\r\n    }\r\n    this.state = \"special authority ignore slashes\";\r\n  } else if (c === 47) {\r\n    this.state = \"authority\";\r\n  } else {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse special authority slashes\"] = function parseSpecialAuthoritySlashes(c) {\r\n  if (c === 47 && this.input[this.pointer + 1] === 47) {\r\n    this.state = \"special authority ignore slashes\";\r\n    ++this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n    this.state = \"special authority ignore slashes\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse special authority ignore slashes\"] = function parseSpecialAuthorityIgnoreSlashes(c) {\r\n  if (c !== 47 && c !== 92) {\r\n    this.state = \"authority\";\r\n    --this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse authority\"] = function parseAuthority(c, cStr) {\r\n  if (c === 64) {\r\n    this.parseError = true;\r\n    if (this.atFlag) {\r\n      this.buffer = \"%40\" + this.buffer;\r\n    }\r\n    this.atFlag = true;\r\n\r\n    // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars\r\n    const len = countSymbols(this.buffer);\r\n    for (let pointer = 0; pointer < len; ++pointer) {\r\n      const codePoint = this.buffer.codePointAt(pointer);\r\n\r\n      if (codePoint === 58 && !this.passwordTokenSeenFlag) {\r\n        this.passwordTokenSeenFlag = true;\r\n        continue;\r\n      }\r\n      const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode);\r\n      if (this.passwordTokenSeenFlag) {\r\n        this.url.password += encodedCodePoints;\r\n      } else {\r\n        this.url.username += encodedCodePoints;\r\n      }\r\n    }\r\n    this.buffer = \"\";\r\n  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||\r\n             (isSpecial(this.url) && c === 92)) {\r\n    if (this.atFlag && this.buffer === \"\") {\r\n      this.parseError = true;\r\n      return failure;\r\n    }\r\n    this.pointer -= countSymbols(this.buffer) + 1;\r\n    this.buffer = \"\";\r\n    this.state = \"host\";\r\n  } else {\r\n    this.buffer += cStr;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse hostname\"] =\r\nURLStateMachine.prototype[\"parse host\"] = function parseHostName(c, cStr) {\r\n  if (this.stateOverride && this.url.scheme === \"file\") {\r\n    --this.pointer;\r\n    this.state = \"file host\";\r\n  } else if (c === 58 && !this.arrFlag) {\r\n    if (this.buffer === \"\") {\r\n      this.parseError = true;\r\n      return failure;\r\n    }\r\n\r\n    const host = parseHost(this.buffer, isSpecial(this.url));\r\n    if (host === failure) {\r\n      return failure;\r\n    }\r\n\r\n    this.url.host = host;\r\n    this.buffer = \"\";\r\n    this.state = \"port\";\r\n    if (this.stateOverride === \"hostname\") {\r\n      return false;\r\n    }\r\n  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||\r\n             (isSpecial(this.url) && c === 92)) {\r\n    --this.pointer;\r\n    if (isSpecial(this.url) && this.buffer === \"\") {\r\n      this.parseError = true;\r\n      return failure;\r\n    } else if (this.stateOverride && this.buffer === \"\" &&\r\n               (includesCredentials(this.url) || this.url.port !== null)) {\r\n      this.parseError = true;\r\n      return false;\r\n    }\r\n\r\n    const host = parseHost(this.buffer, isSpecial(this.url));\r\n    if (host === failure) {\r\n      return failure;\r\n    }\r\n\r\n    this.url.host = host;\r\n    this.buffer = \"\";\r\n    this.state = \"path start\";\r\n    if (this.stateOverride) {\r\n      return false;\r\n    }\r\n  } else {\r\n    if (c === 91) {\r\n      this.arrFlag = true;\r\n    } else if (c === 93) {\r\n      this.arrFlag = false;\r\n    }\r\n    this.buffer += cStr;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse port\"] = function parsePort(c, cStr) {\r\n  if (isASCIIDigit(c)) {\r\n    this.buffer += cStr;\r\n  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||\r\n             (isSpecial(this.url) && c === 92) ||\r\n             this.stateOverride) {\r\n    if (this.buffer !== \"\") {\r\n      const port = parseInt(this.buffer);\r\n      if (port > Math.pow(2, 16) - 1) {\r\n        this.parseError = true;\r\n        return failure;\r\n      }\r\n      this.url.port = port === defaultPort(this.url.scheme) ? null : port;\r\n      this.buffer = \"\";\r\n    }\r\n    if (this.stateOverride) {\r\n      return false;\r\n    }\r\n    this.state = \"path start\";\r\n    --this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n    return failure;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nconst fileOtherwiseCodePoints = new Set([47, 92, 63, 35]);\r\n\r\nURLStateMachine.prototype[\"parse file\"] = function parseFile(c) {\r\n  this.url.scheme = \"file\";\r\n\r\n  if (c === 47 || c === 92) {\r\n    if (c === 92) {\r\n      this.parseError = true;\r\n    }\r\n    this.state = \"file slash\";\r\n  } else if (this.base !== null && this.base.scheme === \"file\") {\r\n    if (isNaN(c)) {\r\n      this.url.host = this.base.host;\r\n      this.url.path = this.base.path.slice();\r\n      this.url.query = this.base.query;\r\n    } else if (c === 63) {\r\n      this.url.host = this.base.host;\r\n      this.url.path = this.base.path.slice();\r\n      this.url.query = \"\";\r\n      this.state = \"query\";\r\n    } else if (c === 35) {\r\n      this.url.host = this.base.host;\r\n      this.url.path = this.base.path.slice();\r\n      this.url.query = this.base.query;\r\n      this.url.fragment = \"\";\r\n      this.state = \"fragment\";\r\n    } else {\r\n      if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points\r\n          !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) ||\r\n          (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points\r\n           !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) {\r\n        this.url.host = this.base.host;\r\n        this.url.path = this.base.path.slice();\r\n        shortenPath(this.url);\r\n      } else {\r\n        this.parseError = true;\r\n      }\r\n\r\n      this.state = \"path\";\r\n      --this.pointer;\r\n    }\r\n  } else {\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse file slash\"] = function parseFileSlash(c) {\r\n  if (c === 47 || c === 92) {\r\n    if (c === 92) {\r\n      this.parseError = true;\r\n    }\r\n    this.state = \"file host\";\r\n  } else {\r\n    if (this.base !== null && this.base.scheme === \"file\") {\r\n      if (isNormalizedWindowsDriveLetterString(this.base.path[0])) {\r\n        this.url.path.push(this.base.path[0]);\r\n      } else {\r\n        this.url.host = this.base.host;\r\n      }\r\n    }\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse file host\"] = function parseFileHost(c, cStr) {\r\n  if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) {\r\n    --this.pointer;\r\n    if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) {\r\n      this.parseError = true;\r\n      this.state = \"path\";\r\n    } else if (this.buffer === \"\") {\r\n      this.url.host = \"\";\r\n      if (this.stateOverride) {\r\n        return false;\r\n      }\r\n      this.state = \"path start\";\r\n    } else {\r\n      let host = parseHost(this.buffer, isSpecial(this.url));\r\n      if (host === failure) {\r\n        return failure;\r\n      }\r\n      if (host === \"localhost\") {\r\n        host = \"\";\r\n      }\r\n      this.url.host = host;\r\n\r\n      if (this.stateOverride) {\r\n        return false;\r\n      }\r\n\r\n      this.buffer = \"\";\r\n      this.state = \"path start\";\r\n    }\r\n  } else {\r\n    this.buffer += cStr;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse path start\"] = function parsePathStart(c) {\r\n  if (isSpecial(this.url)) {\r\n    if (c === 92) {\r\n      this.parseError = true;\r\n    }\r\n    this.state = \"path\";\r\n\r\n    if (c !== 47 && c !== 92) {\r\n      --this.pointer;\r\n    }\r\n  } else if (!this.stateOverride && c === 63) {\r\n    this.url.query = \"\";\r\n    this.state = \"query\";\r\n  } else if (!this.stateOverride && c === 35) {\r\n    this.url.fragment = \"\";\r\n    this.state = \"fragment\";\r\n  } else if (c !== undefined) {\r\n    this.state = \"path\";\r\n    if (c !== 47) {\r\n      --this.pointer;\r\n    }\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse path\"] = function parsePath(c) {\r\n  if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) ||\r\n      (!this.stateOverride && (c === 63 || c === 35))) {\r\n    if (isSpecial(this.url) && c === 92) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    if (isDoubleDot(this.buffer)) {\r\n      shortenPath(this.url);\r\n      if (c !== 47 && !(isSpecial(this.url) && c === 92)) {\r\n        this.url.path.push(\"\");\r\n      }\r\n    } else if (isSingleDot(this.buffer) && c !== 47 &&\r\n               !(isSpecial(this.url) && c === 92)) {\r\n      this.url.path.push(\"\");\r\n    } else if (!isSingleDot(this.buffer)) {\r\n      if (this.url.scheme === \"file\" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) {\r\n        if (this.url.host !== \"\" && this.url.host !== null) {\r\n          this.parseError = true;\r\n          this.url.host = \"\";\r\n        }\r\n        this.buffer = this.buffer[0] + \":\";\r\n      }\r\n      this.url.path.push(this.buffer);\r\n    }\r\n    this.buffer = \"\";\r\n    if (this.url.scheme === \"file\" && (c === undefined || c === 63 || c === 35)) {\r\n      while (this.url.path.length > 1 && this.url.path[0] === \"\") {\r\n        this.parseError = true;\r\n        this.url.path.shift();\r\n      }\r\n    }\r\n    if (c === 63) {\r\n      this.url.query = \"\";\r\n      this.state = \"query\";\r\n    }\r\n    if (c === 35) {\r\n      this.url.fragment = \"\";\r\n      this.state = \"fragment\";\r\n    }\r\n  } else {\r\n    // TODO: If c is not a URL code point and not \"%\", parse error.\r\n\r\n    if (c === 37 &&\r\n      (!isASCIIHex(this.input[this.pointer + 1]) ||\r\n        !isASCIIHex(this.input[this.pointer + 2]))) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    this.buffer += percentEncodeChar(c, isPathPercentEncode);\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse cannot-be-a-base-URL path\"] = function parseCannotBeABaseURLPath(c) {\r\n  if (c === 63) {\r\n    this.url.query = \"\";\r\n    this.state = \"query\";\r\n  } else if (c === 35) {\r\n    this.url.fragment = \"\";\r\n    this.state = \"fragment\";\r\n  } else {\r\n    // TODO: Add: not a URL code point\r\n    if (!isNaN(c) && c !== 37) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    if (c === 37 &&\r\n        (!isASCIIHex(this.input[this.pointer + 1]) ||\r\n         !isASCIIHex(this.input[this.pointer + 2]))) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    if (!isNaN(c)) {\r\n      this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode);\r\n    }\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse query\"] = function parseQuery(c, cStr) {\r\n  if (isNaN(c) || (!this.stateOverride && c === 35)) {\r\n    if (!isSpecial(this.url) || this.url.scheme === \"ws\" || this.url.scheme === \"wss\") {\r\n      this.encodingOverride = \"utf-8\";\r\n    }\r\n\r\n    const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead\r\n    for (let i = 0; i < buffer.length; ++i) {\r\n      if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 ||\r\n          buffer[i] === 0x3C || buffer[i] === 0x3E) {\r\n        this.url.query += percentEncode(buffer[i]);\r\n      } else {\r\n        this.url.query += String.fromCodePoint(buffer[i]);\r\n      }\r\n    }\r\n\r\n    this.buffer = \"\";\r\n    if (c === 35) {\r\n      this.url.fragment = \"\";\r\n      this.state = \"fragment\";\r\n    }\r\n  } else {\r\n    // TODO: If c is not a URL code point and not \"%\", parse error.\r\n    if (c === 37 &&\r\n      (!isASCIIHex(this.input[this.pointer + 1]) ||\r\n        !isASCIIHex(this.input[this.pointer + 2]))) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    this.buffer += cStr;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse fragment\"] = function parseFragment(c) {\r\n  if (isNaN(c)) { // do nothing\r\n  } else if (c === 0x0) {\r\n    this.parseError = true;\r\n  } else {\r\n    // TODO: If c is not a URL code point and not \"%\", parse error.\r\n    if (c === 37 &&\r\n      (!isASCIIHex(this.input[this.pointer + 1]) ||\r\n        !isASCIIHex(this.input[this.pointer + 2]))) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode);\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nfunction serializeURL(url, excludeFragment) {\r\n  let output = url.scheme + \":\";\r\n  if (url.host !== null) {\r\n    output += \"//\";\r\n\r\n    if (url.username !== \"\" || url.password !== \"\") {\r\n      output += url.username;\r\n      if (url.password !== \"\") {\r\n        output += \":\" + url.password;\r\n      }\r\n      output += \"@\";\r\n    }\r\n\r\n    output += serializeHost(url.host);\r\n\r\n    if (url.port !== null) {\r\n      output += \":\" + url.port;\r\n    }\r\n  } else if (url.host === null && url.scheme === \"file\") {\r\n    output += \"//\";\r\n  }\r\n\r\n  if (url.cannotBeABaseURL) {\r\n    output += url.path[0];\r\n  } else {\r\n    for (const string of url.path) {\r\n      output += \"/\" + string;\r\n    }\r\n  }\r\n\r\n  if (url.query !== null) {\r\n    output += \"?\" + url.query;\r\n  }\r\n\r\n  if (!excludeFragment && url.fragment !== null) {\r\n    output += \"#\" + url.fragment;\r\n  }\r\n\r\n  return output;\r\n}\r\n\r\nfunction serializeOrigin(tuple) {\r\n  let result = tuple.scheme + \"://\";\r\n  result += serializeHost(tuple.host);\r\n\r\n  if (tuple.port !== null) {\r\n    result += \":\" + tuple.port;\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\nmodule.exports.serializeURL = serializeURL;\r\n\r\nmodule.exports.serializeURLOrigin = function (url) {\r\n  // https://url.spec.whatwg.org/#concept-url-origin\r\n  switch (url.scheme) {\r\n    case \"blob\":\r\n      try {\r\n        return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0]));\r\n      } catch (e) {\r\n        // serializing an opaque origin returns \"null\"\r\n        return \"null\";\r\n      }\r\n    case \"ftp\":\r\n    case \"gopher\":\r\n    case \"http\":\r\n    case \"https\":\r\n    case \"ws\":\r\n    case \"wss\":\r\n      return serializeOrigin({\r\n        scheme: url.scheme,\r\n        host: url.host,\r\n        port: url.port\r\n      });\r\n    case \"file\":\r\n      // spec says \"exercise to the reader\", chrome says \"file://\"\r\n      return \"file://\";\r\n    default:\r\n      // serializing an opaque origin returns \"null\"\r\n      return \"null\";\r\n  }\r\n};\r\n\r\nmodule.exports.basicURLParse = function (input, options) {\r\n  if (options === undefined) {\r\n    options = {};\r\n  }\r\n\r\n  const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride);\r\n  if (usm.failure) {\r\n    return \"failure\";\r\n  }\r\n\r\n  return usm.url;\r\n};\r\n\r\nmodule.exports.setTheUsername = function (url, username) {\r\n  url.username = \"\";\r\n  const decoded = punycode.ucs2.decode(username);\r\n  for (let i = 0; i < decoded.length; ++i) {\r\n    url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode);\r\n  }\r\n};\r\n\r\nmodule.exports.setThePassword = function (url, password) {\r\n  url.password = \"\";\r\n  const decoded = punycode.ucs2.decode(password);\r\n  for (let i = 0; i < decoded.length; ++i) {\r\n    url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode);\r\n  }\r\n};\r\n\r\nmodule.exports.serializeHost = serializeHost;\r\n\r\nmodule.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort;\r\n\r\nmodule.exports.serializeInteger = function (integer) {\r\n  return String(integer);\r\n};\r\n\r\nmodule.exports.parseURL = function (input, options) {\r\n  if (options === undefined) {\r\n    options = {};\r\n  }\r\n\r\n  // We don't handle blobs, so this just delegates:\r\n  return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride });\r\n};\r\n\n\n/***/ }),\n\n/***/ 3185:\n/***/ ((module) => {\n\n\"use strict\";\n\n\nmodule.exports.mixin = function mixin(target, source) {\n  const keys = Object.getOwnPropertyNames(source);\n  for (let i = 0; i < keys.length; ++i) {\n    Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i]));\n  }\n};\n\nmodule.exports.wrapperSymbol = Symbol(\"wrapper\");\nmodule.exports.implSymbol = Symbol(\"impl\");\n\nmodule.exports.wrapperForImpl = function (impl) {\n  return impl[module.exports.wrapperSymbol];\n};\n\nmodule.exports.implForWrapper = function (wrapper) {\n  return wrapper[module.exports.implSymbol];\n};\n\n\n\n/***/ }),\n\n/***/ 2940:\n/***/ ((module) => {\n\n// Returns a wrapper function that returns a wrapped callback\n// The wrapper function should do some stuff, and return a\n// presumably different callback function.\n// This makes sure that own properties are retained, so that\n// decorations and such are not lost along the way.\nmodule.exports = wrappy\nfunction wrappy (fn, cb) {\n  if (fn && cb) return wrappy(fn)(cb)\n\n  if (typeof fn !== 'function')\n    throw new TypeError('need wrapper function')\n\n  Object.keys(fn).forEach(function (k) {\n    wrapper[k] = fn[k]\n  })\n\n  return wrapper\n\n  function wrapper() {\n    var args = new Array(arguments.length)\n    for (var i = 0; i < args.length; i++) {\n      args[i] = arguments[i]\n    }\n    var ret = fn.apply(this, args)\n    var cb = args[args.length-1]\n    if (typeof ret === 'function' && ret !== cb) {\n      Object.keys(cb).forEach(function (k) {\n        ret[k] = cb[k]\n      })\n    }\n    return ret\n  }\n}\n\n\n/***/ }),\n\n/***/ 2877:\n/***/ ((module) => {\n\nmodule.exports = eval(\"require\")(\"encoding\");\n\n\n/***/ }),\n\n/***/ 68:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = JSON.parse(\"[[[0,44],\\\"disallowed_STD3_valid\\\"],[[45,46],\\\"valid\\\"],[[47,47],\\\"disallowed_STD3_valid\\\"],[[48,57],\\\"valid\\\"],[[58,64],\\\"disallowed_STD3_valid\\\"],[[65,65],\\\"mapped\\\",[97]],[[66,66],\\\"mapped\\\",[98]],[[67,67],\\\"mapped\\\",[99]],[[68,68],\\\"mapped\\\",[100]],[[69,69],\\\"mapped\\\",[101]],[[70,70],\\\"mapped\\\",[102]],[[71,71],\\\"mapped\\\",[103]],[[72,72],\\\"mapped\\\",[104]],[[73,73],\\\"mapped\\\",[105]],[[74,74],\\\"mapped\\\",[106]],[[75,75],\\\"mapped\\\",[107]],[[76,76],\\\"mapped\\\",[108]],[[77,77],\\\"mapped\\\",[109]],[[78,78],\\\"mapped\\\",[110]],[[79,79],\\\"mapped\\\",[111]],[[80,80],\\\"mapped\\\",[112]],[[81,81],\\\"mapped\\\",[113]],[[82,82],\\\"mapped\\\",[114]],[[83,83],\\\"mapped\\\",[115]],[[84,84],\\\"mapped\\\",[116]],[[85,85],\\\"mapped\\\",[117]],[[86,86],\\\"mapped\\\",[118]],[[87,87],\\\"mapped\\\",[119]],[[88,88],\\\"mapped\\\",[120]],[[89,89],\\\"mapped\\\",[121]],[[90,90],\\\"mapped\\\",[122]],[[91,96],\\\"disallowed_STD3_valid\\\"],[[97,122],\\\"valid\\\"],[[123,127],\\\"disallowed_STD3_valid\\\"],[[128,159],\\\"disallowed\\\"],[[160,160],\\\"disallowed_STD3_mapped\\\",[32]],[[161,167],\\\"valid\\\",[],\\\"NV8\\\"],[[168,168],\\\"disallowed_STD3_mapped\\\",[32,776]],[[169,169],\\\"valid\\\",[],\\\"NV8\\\"],[[170,170],\\\"mapped\\\",[97]],[[171,172],\\\"valid\\\",[],\\\"NV8\\\"],[[173,173],\\\"ignored\\\"],[[174,174],\\\"valid\\\",[],\\\"NV8\\\"],[[175,175],\\\"disallowed_STD3_mapped\\\",[32,772]],[[176,177],\\\"valid\\\",[],\\\"NV8\\\"],[[178,178],\\\"mapped\\\",[50]],[[179,179],\\\"mapped\\\",[51]],[[180,180],\\\"disallowed_STD3_mapped\\\",[32,769]],[[181,181],\\\"mapped\\\",[956]],[[182,182],\\\"valid\\\",[],\\\"NV8\\\"],[[183,183],\\\"valid\\\"],[[184,184],\\\"disallowed_STD3_mapped\\\",[32,807]],[[185,185],\\\"mapped\\\",[49]],[[186,186],\\\"mapped\\\",[111]],[[187,187],\\\"valid\\\",[],\\\"NV8\\\"],[[188,188],\\\"mapped\\\",[49,8260,52]],[[189,189],\\\"mapped\\\",[49,8260,50]],[[190,190],\\\"mapped\\\",[51,8260,52]],[[191,191],\\\"valid\\\",[],\\\"NV8\\\"],[[192,192],\\\"mapped\\\",[224]],[[193,193],\\\"mapped\\\",[225]],[[194,194],\\\"mapped\\\",[226]],[[195,195],\\\"mapped\\\",[227]],[[196,196],\\\"mapped\\\",[228]],[[197,197],\\\"mapped\\\",[229]],[[198,198],\\\"mapped\\\",[230]],[[199,199],\\\"mapped\\\",[231]],[[200,200],\\\"mapped\\\",[232]],[[201,201],\\\"mapped\\\",[233]],[[202,202],\\\"mapped\\\",[234]],[[203,203],\\\"mapped\\\",[235]],[[204,204],\\\"mapped\\\",[236]],[[205,205],\\\"mapped\\\",[237]],[[206,206],\\\"mapped\\\",[238]],[[207,207],\\\"mapped\\\",[239]],[[208,208],\\\"mapped\\\",[240]],[[209,209],\\\"mapped\\\",[241]],[[210,210],\\\"mapped\\\",[242]],[[211,211],\\\"mapped\\\",[243]],[[212,212],\\\"mapped\\\",[244]],[[213,213],\\\"mapped\\\",[245]],[[214,214],\\\"mapped\\\",[246]],[[215,215],\\\"valid\\\",[],\\\"NV8\\\"],[[216,216],\\\"mapped\\\",[248]],[[217,217],\\\"mapped\\\",[249]],[[218,218],\\\"mapped\\\",[250]],[[219,219],\\\"mapped\\\",[251]],[[220,220],\\\"mapped\\\",[252]],[[221,221],\\\"mapped\\\",[253]],[[222,222],\\\"mapped\\\",[254]],[[223,223],\\\"deviation\\\",[115,115]],[[224,246],\\\"valid\\\"],[[247,247],\\\"valid\\\",[],\\\"NV8\\\"],[[248,255],\\\"valid\\\"],[[256,256],\\\"mapped\\\",[257]],[[257,257],\\\"valid\\\"],[[258,258],\\\"mapped\\\",[259]],[[259,259],\\\"valid\\\"],[[260,260],\\\"mapped\\\",[261]],[[261,261],\\\"valid\\\"],[[262,262],\\\"mapped\\\",[263]],[[263,263],\\\"valid\\\"],[[264,264],\\\"mapped\\\",[265]],[[265,265],\\\"valid\\\"],[[266,266],\\\"mapped\\\",[267]],[[267,267],\\\"valid\\\"],[[268,268],\\\"mapped\\\",[269]],[[269,269],\\\"valid\\\"],[[270,270],\\\"mapped\\\",[271]],[[271,271],\\\"valid\\\"],[[272,272],\\\"mapped\\\",[273]],[[273,273],\\\"valid\\\"],[[274,274],\\\"mapped\\\",[275]],[[275,275],\\\"valid\\\"],[[276,276],\\\"mapped\\\",[277]],[[277,277],\\\"valid\\\"],[[278,278],\\\"mapped\\\",[279]],[[279,279],\\\"valid\\\"],[[280,280],\\\"mapped\\\",[281]],[[281,281],\\\"valid\\\"],[[282,282],\\\"mapped\\\",[283]],[[283,283],\\\"valid\\\"],[[284,284],\\\"mapped\\\",[285]],[[285,285],\\\"valid\\\"],[[286,286],\\\"mapped\\\",[287]],[[287,287],\\\"valid\\\"],[[288,288],\\\"mapped\\\",[289]],[[289,289],\\\"valid\\\"],[[290,290],\\\"mapped\\\",[291]],[[291,291],\\\"valid\\\"],[[292,292],\\\"mapped\\\",[293]],[[293,293],\\\"valid\\\"],[[294,294],\\\"mapped\\\",[295]],[[295,295],\\\"valid\\\"],[[296,296],\\\"mapped\\\",[297]],[[297,297],\\\"valid\\\"],[[298,298],\\\"mapped\\\",[299]],[[299,299],\\\"valid\\\"],[[300,300],\\\"mapped\\\",[301]],[[301,301],\\\"valid\\\"],[[302,302],\\\"mapped\\\",[303]],[[303,303],\\\"valid\\\"],[[304,304],\\\"mapped\\\",[105,775]],[[305,305],\\\"valid\\\"],[[306,307],\\\"mapped\\\",[105,106]],[[308,308],\\\"mapped\\\",[309]],[[309,309],\\\"valid\\\"],[[310,310],\\\"mapped\\\",[311]],[[311,312],\\\"valid\\\"],[[313,313],\\\"mapped\\\",[314]],[[314,314],\\\"valid\\\"],[[315,315],\\\"mapped\\\",[316]],[[316,316],\\\"valid\\\"],[[317,317],\\\"mapped\\\",[318]],[[318,318],\\\"valid\\\"],[[319,320],\\\"mapped\\\",[108,183]],[[321,321],\\\"mapped\\\",[322]],[[322,322],\\\"valid\\\"],[[323,323],\\\"mapped\\\",[324]],[[324,324],\\\"valid\\\"],[[325,325],\\\"mapped\\\",[326]],[[326,326],\\\"valid\\\"],[[327,327],\\\"mapped\\\",[328]],[[328,328],\\\"valid\\\"],[[329,329],\\\"mapped\\\",[700,110]],[[330,330],\\\"mapped\\\",[331]],[[331,331],\\\"valid\\\"],[[332,332],\\\"mapped\\\",[333]],[[333,333],\\\"valid\\\"],[[334,334],\\\"mapped\\\",[335]],[[335,335],\\\"valid\\\"],[[336,336],\\\"mapped\\\",[337]],[[337,337],\\\"valid\\\"],[[338,338],\\\"mapped\\\",[339]],[[339,339],\\\"valid\\\"],[[340,340],\\\"mapped\\\",[341]],[[341,341],\\\"valid\\\"],[[342,342],\\\"mapped\\\",[343]],[[343,343],\\\"valid\\\"],[[344,344],\\\"mapped\\\",[345]],[[345,345],\\\"valid\\\"],[[346,346],\\\"mapped\\\",[347]],[[347,347],\\\"valid\\\"],[[348,348],\\\"mapped\\\",[349]],[[349,349],\\\"valid\\\"],[[350,350],\\\"mapped\\\",[351]],[[351,351],\\\"valid\\\"],[[352,352],\\\"mapped\\\",[353]],[[353,353],\\\"valid\\\"],[[354,354],\\\"mapped\\\",[355]],[[355,355],\\\"valid\\\"],[[356,356],\\\"mapped\\\",[357]],[[357,357],\\\"valid\\\"],[[358,358],\\\"mapped\\\",[359]],[[359,359],\\\"valid\\\"],[[360,360],\\\"mapped\\\",[361]],[[361,361],\\\"valid\\\"],[[362,362],\\\"mapped\\\",[363]],[[363,363],\\\"valid\\\"],[[364,364],\\\"mapped\\\",[365]],[[365,365],\\\"valid\\\"],[[366,366],\\\"mapped\\\",[367]],[[367,367],\\\"valid\\\"],[[368,368],\\\"mapped\\\",[369]],[[369,369],\\\"valid\\\"],[[370,370],\\\"mapped\\\",[371]],[[371,371],\\\"valid\\\"],[[372,372],\\\"mapped\\\",[373]],[[373,373],\\\"valid\\\"],[[374,374],\\\"mapped\\\",[375]],[[375,375],\\\"valid\\\"],[[376,376],\\\"mapped\\\",[255]],[[377,377],\\\"mapped\\\",[378]],[[378,378],\\\"valid\\\"],[[379,379],\\\"mapped\\\",[380]],[[380,380],\\\"valid\\\"],[[381,381],\\\"mapped\\\",[382]],[[382,382],\\\"valid\\\"],[[383,383],\\\"mapped\\\",[115]],[[384,384],\\\"valid\\\"],[[385,385],\\\"mapped\\\",[595]],[[386,386],\\\"mapped\\\",[387]],[[387,387],\\\"valid\\\"],[[388,388],\\\"mapped\\\",[389]],[[389,389],\\\"valid\\\"],[[390,390],\\\"mapped\\\",[596]],[[391,391],\\\"mapped\\\",[392]],[[392,392],\\\"valid\\\"],[[393,393],\\\"mapped\\\",[598]],[[394,394],\\\"mapped\\\",[599]],[[395,395],\\\"mapped\\\",[396]],[[396,397],\\\"valid\\\"],[[398,398],\\\"mapped\\\",[477]],[[399,399],\\\"mapped\\\",[601]],[[400,400],\\\"mapped\\\",[603]],[[401,401],\\\"mapped\\\",[402]],[[402,402],\\\"valid\\\"],[[403,403],\\\"mapped\\\",[608]],[[404,404],\\\"mapped\\\",[611]],[[405,405],\\\"valid\\\"],[[406,406],\\\"mapped\\\",[617]],[[407,407],\\\"mapped\\\",[616]],[[408,408],\\\"mapped\\\",[409]],[[409,411],\\\"valid\\\"],[[412,412],\\\"mapped\\\",[623]],[[413,413],\\\"mapped\\\",[626]],[[414,414],\\\"valid\\\"],[[415,415],\\\"mapped\\\",[629]],[[416,416],\\\"mapped\\\",[417]],[[417,417],\\\"valid\\\"],[[418,418],\\\"mapped\\\",[419]],[[419,419],\\\"valid\\\"],[[420,420],\\\"mapped\\\",[421]],[[421,421],\\\"valid\\\"],[[422,422],\\\"mapped\\\",[640]],[[423,423],\\\"mapped\\\",[424]],[[424,424],\\\"valid\\\"],[[425,425],\\\"mapped\\\",[643]],[[426,427],\\\"valid\\\"],[[428,428],\\\"mapped\\\",[429]],[[429,429],\\\"valid\\\"],[[430,430],\\\"mapped\\\",[648]],[[431,431],\\\"mapped\\\",[432]],[[432,432],\\\"valid\\\"],[[433,433],\\\"mapped\\\",[650]],[[434,434],\\\"mapped\\\",[651]],[[435,435],\\\"mapped\\\",[436]],[[436,436],\\\"valid\\\"],[[437,437],\\\"mapped\\\",[438]],[[438,438],\\\"valid\\\"],[[439,439],\\\"mapped\\\",[658]],[[440,440],\\\"mapped\\\",[441]],[[441,443],\\\"valid\\\"],[[444,444],\\\"mapped\\\",[445]],[[445,451],\\\"valid\\\"],[[452,454],\\\"mapped\\\",[100,382]],[[455,457],\\\"mapped\\\",[108,106]],[[458,460],\\\"mapped\\\",[110,106]],[[461,461],\\\"mapped\\\",[462]],[[462,462],\\\"valid\\\"],[[463,463],\\\"mapped\\\",[464]],[[464,464],\\\"valid\\\"],[[465,465],\\\"mapped\\\",[466]],[[466,466],\\\"valid\\\"],[[467,467],\\\"mapped\\\",[468]],[[468,468],\\\"valid\\\"],[[469,469],\\\"mapped\\\",[470]],[[470,470],\\\"valid\\\"],[[471,471],\\\"mapped\\\",[472]],[[472,472],\\\"valid\\\"],[[473,473],\\\"mapped\\\",[474]],[[474,474],\\\"valid\\\"],[[475,475],\\\"mapped\\\",[476]],[[476,477],\\\"valid\\\"],[[478,478],\\\"mapped\\\",[479]],[[479,479],\\\"valid\\\"],[[480,480],\\\"mapped\\\",[481]],[[481,481],\\\"valid\\\"],[[482,482],\\\"mapped\\\",[483]],[[483,483],\\\"valid\\\"],[[484,484],\\\"mapped\\\",[485]],[[485,485],\\\"valid\\\"],[[486,486],\\\"mapped\\\",[487]],[[487,487],\\\"valid\\\"],[[488,488],\\\"mapped\\\",[489]],[[489,489],\\\"valid\\\"],[[490,490],\\\"mapped\\\",[491]],[[491,491],\\\"valid\\\"],[[492,492],\\\"mapped\\\",[493]],[[493,493],\\\"valid\\\"],[[494,494],\\\"mapped\\\",[495]],[[495,496],\\\"valid\\\"],[[497,499],\\\"mapped\\\",[100,122]],[[500,500],\\\"mapped\\\",[501]],[[501,501],\\\"valid\\\"],[[502,502],\\\"mapped\\\",[405]],[[503,503],\\\"mapped\\\",[447]],[[504,504],\\\"mapped\\\",[505]],[[505,505],\\\"valid\\\"],[[506,506],\\\"mapped\\\",[507]],[[507,507],\\\"valid\\\"],[[508,508],\\\"mapped\\\",[509]],[[509,509],\\\"valid\\\"],[[510,510],\\\"mapped\\\",[511]],[[511,511],\\\"valid\\\"],[[512,512],\\\"mapped\\\",[513]],[[513,513],\\\"valid\\\"],[[514,514],\\\"mapped\\\",[515]],[[515,515],\\\"valid\\\"],[[516,516],\\\"mapped\\\",[517]],[[517,517],\\\"valid\\\"],[[518,518],\\\"mapped\\\",[519]],[[519,519],\\\"valid\\\"],[[520,520],\\\"mapped\\\",[521]],[[521,521],\\\"valid\\\"],[[522,522],\\\"mapped\\\",[523]],[[523,523],\\\"valid\\\"],[[524,524],\\\"mapped\\\",[525]],[[525,525],\\\"valid\\\"],[[526,526],\\\"mapped\\\",[527]],[[527,527],\\\"valid\\\"],[[528,528],\\\"mapped\\\",[529]],[[529,529],\\\"valid\\\"],[[530,530],\\\"mapped\\\",[531]],[[531,531],\\\"valid\\\"],[[532,532],\\\"mapped\\\",[533]],[[533,533],\\\"valid\\\"],[[534,534],\\\"mapped\\\",[535]],[[535,535],\\\"valid\\\"],[[536,536],\\\"mapped\\\",[537]],[[537,537],\\\"valid\\\"],[[538,538],\\\"mapped\\\",[539]],[[539,539],\\\"valid\\\"],[[540,540],\\\"mapped\\\",[541]],[[541,541],\\\"valid\\\"],[[542,542],\\\"mapped\\\",[543]],[[543,543],\\\"valid\\\"],[[544,544],\\\"mapped\\\",[414]],[[545,545],\\\"valid\\\"],[[546,546],\\\"mapped\\\",[547]],[[547,547],\\\"valid\\\"],[[548,548],\\\"mapped\\\",[549]],[[549,549],\\\"valid\\\"],[[550,550],\\\"mapped\\\",[551]],[[551,551],\\\"valid\\\"],[[552,552],\\\"mapped\\\",[553]],[[553,553],\\\"valid\\\"],[[554,554],\\\"mapped\\\",[555]],[[555,555],\\\"valid\\\"],[[556,556],\\\"mapped\\\",[557]],[[557,557],\\\"valid\\\"],[[558,558],\\\"mapped\\\",[559]],[[559,559],\\\"valid\\\"],[[560,560],\\\"mapped\\\",[561]],[[561,561],\\\"valid\\\"],[[562,562],\\\"mapped\\\",[563]],[[563,563],\\\"valid\\\"],[[564,566],\\\"valid\\\"],[[567,569],\\\"valid\\\"],[[570,570],\\\"mapped\\\",[11365]],[[571,571],\\\"mapped\\\",[572]],[[572,572],\\\"valid\\\"],[[573,573],\\\"mapped\\\",[410]],[[574,574],\\\"mapped\\\",[11366]],[[575,576],\\\"valid\\\"],[[577,577],\\\"mapped\\\",[578]],[[578,578],\\\"valid\\\"],[[579,579],\\\"mapped\\\",[384]],[[580,580],\\\"mapped\\\",[649]],[[581,581],\\\"mapped\\\",[652]],[[582,582],\\\"mapped\\\",[583]],[[583,583],\\\"valid\\\"],[[584,584],\\\"mapped\\\",[585]],[[585,585],\\\"valid\\\"],[[586,586],\\\"mapped\\\",[587]],[[587,587],\\\"valid\\\"],[[588,588],\\\"mapped\\\",[589]],[[589,589],\\\"valid\\\"],[[590,590],\\\"mapped\\\",[591]],[[591,591],\\\"valid\\\"],[[592,680],\\\"valid\\\"],[[681,685],\\\"valid\\\"],[[686,687],\\\"valid\\\"],[[688,688],\\\"mapped\\\",[104]],[[689,689],\\\"mapped\\\",[614]],[[690,690],\\\"mapped\\\",[106]],[[691,691],\\\"mapped\\\",[114]],[[692,692],\\\"mapped\\\",[633]],[[693,693],\\\"mapped\\\",[635]],[[694,694],\\\"mapped\\\",[641]],[[695,695],\\\"mapped\\\",[119]],[[696,696],\\\"mapped\\\",[121]],[[697,705],\\\"valid\\\"],[[706,709],\\\"valid\\\",[],\\\"NV8\\\"],[[710,721],\\\"valid\\\"],[[722,727],\\\"valid\\\",[],\\\"NV8\\\"],[[728,728],\\\"disallowed_STD3_mapped\\\",[32,774]],[[729,729],\\\"disallowed_STD3_mapped\\\",[32,775]],[[730,730],\\\"disallowed_STD3_mapped\\\",[32,778]],[[731,731],\\\"disallowed_STD3_mapped\\\",[32,808]],[[732,732],\\\"disallowed_STD3_mapped\\\",[32,771]],[[733,733],\\\"disallowed_STD3_mapped\\\",[32,779]],[[734,734],\\\"valid\\\",[],\\\"NV8\\\"],[[735,735],\\\"valid\\\",[],\\\"NV8\\\"],[[736,736],\\\"mapped\\\",[611]],[[737,737],\\\"mapped\\\",[108]],[[738,738],\\\"mapped\\\",[115]],[[739,739],\\\"mapped\\\",[120]],[[740,740],\\\"mapped\\\",[661]],[[741,745],\\\"valid\\\",[],\\\"NV8\\\"],[[746,747],\\\"valid\\\",[],\\\"NV8\\\"],[[748,748],\\\"valid\\\"],[[749,749],\\\"valid\\\",[],\\\"NV8\\\"],[[750,750],\\\"valid\\\"],[[751,767],\\\"valid\\\",[],\\\"NV8\\\"],[[768,831],\\\"valid\\\"],[[832,832],\\\"mapped\\\",[768]],[[833,833],\\\"mapped\\\",[769]],[[834,834],\\\"valid\\\"],[[835,835],\\\"mapped\\\",[787]],[[836,836],\\\"mapped\\\",[776,769]],[[837,837],\\\"mapped\\\",[953]],[[838,846],\\\"valid\\\"],[[847,847],\\\"ignored\\\"],[[848,855],\\\"valid\\\"],[[856,860],\\\"valid\\\"],[[861,863],\\\"valid\\\"],[[864,865],\\\"valid\\\"],[[866,866],\\\"valid\\\"],[[867,879],\\\"valid\\\"],[[880,880],\\\"mapped\\\",[881]],[[881,881],\\\"valid\\\"],[[882,882],\\\"mapped\\\",[883]],[[883,883],\\\"valid\\\"],[[884,884],\\\"mapped\\\",[697]],[[885,885],\\\"valid\\\"],[[886,886],\\\"mapped\\\",[887]],[[887,887],\\\"valid\\\"],[[888,889],\\\"disallowed\\\"],[[890,890],\\\"disallowed_STD3_mapped\\\",[32,953]],[[891,893],\\\"valid\\\"],[[894,894],\\\"disallowed_STD3_mapped\\\",[59]],[[895,895],\\\"mapped\\\",[1011]],[[896,899],\\\"disallowed\\\"],[[900,900],\\\"disallowed_STD3_mapped\\\",[32,769]],[[901,901],\\\"disallowed_STD3_mapped\\\",[32,776,769]],[[902,902],\\\"mapped\\\",[940]],[[903,903],\\\"mapped\\\",[183]],[[904,904],\\\"mapped\\\",[941]],[[905,905],\\\"mapped\\\",[942]],[[906,906],\\\"mapped\\\",[943]],[[907,907],\\\"disallowed\\\"],[[908,908],\\\"mapped\\\",[972]],[[909,909],\\\"disallowed\\\"],[[910,910],\\\"mapped\\\",[973]],[[911,911],\\\"mapped\\\",[974]],[[912,912],\\\"valid\\\"],[[913,913],\\\"mapped\\\",[945]],[[914,914],\\\"mapped\\\",[946]],[[915,915],\\\"mapped\\\",[947]],[[916,916],\\\"mapped\\\",[948]],[[917,917],\\\"mapped\\\",[949]],[[918,918],\\\"mapped\\\",[950]],[[919,919],\\\"mapped\\\",[951]],[[920,920],\\\"mapped\\\",[952]],[[921,921],\\\"mapped\\\",[953]],[[922,922],\\\"mapped\\\",[954]],[[923,923],\\\"mapped\\\",[955]],[[924,924],\\\"mapped\\\",[956]],[[925,925],\\\"mapped\\\",[957]],[[926,926],\\\"mapped\\\",[958]],[[927,927],\\\"mapped\\\",[959]],[[928,928],\\\"mapped\\\",[960]],[[929,929],\\\"mapped\\\",[961]],[[930,930],\\\"disallowed\\\"],[[931,931],\\\"mapped\\\",[963]],[[932,932],\\\"mapped\\\",[964]],[[933,933],\\\"mapped\\\",[965]],[[934,934],\\\"mapped\\\",[966]],[[935,935],\\\"mapped\\\",[967]],[[936,936],\\\"mapped\\\",[968]],[[937,937],\\\"mapped\\\",[969]],[[938,938],\\\"mapped\\\",[970]],[[939,939],\\\"mapped\\\",[971]],[[940,961],\\\"valid\\\"],[[962,962],\\\"deviation\\\",[963]],[[963,974],\\\"valid\\\"],[[975,975],\\\"mapped\\\",[983]],[[976,976],\\\"mapped\\\",[946]],[[977,977],\\\"mapped\\\",[952]],[[978,978],\\\"mapped\\\",[965]],[[979,979],\\\"mapped\\\",[973]],[[980,980],\\\"mapped\\\",[971]],[[981,981],\\\"mapped\\\",[966]],[[982,982],\\\"mapped\\\",[960]],[[983,983],\\\"valid\\\"],[[984,984],\\\"mapped\\\",[985]],[[985,985],\\\"valid\\\"],[[986,986],\\\"mapped\\\",[987]],[[987,987],\\\"valid\\\"],[[988,988],\\\"mapped\\\",[989]],[[989,989],\\\"valid\\\"],[[990,990],\\\"mapped\\\",[991]],[[991,991],\\\"valid\\\"],[[992,992],\\\"mapped\\\",[993]],[[993,993],\\\"valid\\\"],[[994,994],\\\"mapped\\\",[995]],[[995,995],\\\"valid\\\"],[[996,996],\\\"mapped\\\",[997]],[[997,997],\\\"valid\\\"],[[998,998],\\\"mapped\\\",[999]],[[999,999],\\\"valid\\\"],[[1000,1000],\\\"mapped\\\",[1001]],[[1001,1001],\\\"valid\\\"],[[1002,1002],\\\"mapped\\\",[1003]],[[1003,1003],\\\"valid\\\"],[[1004,1004],\\\"mapped\\\",[1005]],[[1005,1005],\\\"valid\\\"],[[1006,1006],\\\"mapped\\\",[1007]],[[1007,1007],\\\"valid\\\"],[[1008,1008],\\\"mapped\\\",[954]],[[1009,1009],\\\"mapped\\\",[961]],[[1010,1010],\\\"mapped\\\",[963]],[[1011,1011],\\\"valid\\\"],[[1012,1012],\\\"mapped\\\",[952]],[[1013,1013],\\\"mapped\\\",[949]],[[1014,1014],\\\"valid\\\",[],\\\"NV8\\\"],[[1015,1015],\\\"mapped\\\",[1016]],[[1016,1016],\\\"valid\\\"],[[1017,1017],\\\"mapped\\\",[963]],[[1018,1018],\\\"mapped\\\",[1019]],[[1019,1019],\\\"valid\\\"],[[1020,1020],\\\"valid\\\"],[[1021,1021],\\\"mapped\\\",[891]],[[1022,1022],\\\"mapped\\\",[892]],[[1023,1023],\\\"mapped\\\",[893]],[[1024,1024],\\\"mapped\\\",[1104]],[[1025,1025],\\\"mapped\\\",[1105]],[[1026,1026],\\\"mapped\\\",[1106]],[[1027,1027],\\\"mapped\\\",[1107]],[[1028,1028],\\\"mapped\\\",[1108]],[[1029,1029],\\\"mapped\\\",[1109]],[[1030,1030],\\\"mapped\\\",[1110]],[[1031,1031],\\\"mapped\\\",[1111]],[[1032,1032],\\\"mapped\\\",[1112]],[[1033,1033],\\\"mapped\\\",[1113]],[[1034,1034],\\\"mapped\\\",[1114]],[[1035,1035],\\\"mapped\\\",[1115]],[[1036,1036],\\\"mapped\\\",[1116]],[[1037,1037],\\\"mapped\\\",[1117]],[[1038,1038],\\\"mapped\\\",[1118]],[[1039,1039],\\\"mapped\\\",[1119]],[[1040,1040],\\\"mapped\\\",[1072]],[[1041,1041],\\\"mapped\\\",[1073]],[[1042,1042],\\\"mapped\\\",[1074]],[[1043,1043],\\\"mapped\\\",[1075]],[[1044,1044],\\\"mapped\\\",[1076]],[[1045,1045],\\\"mapped\\\",[1077]],[[1046,1046],\\\"mapped\\\",[1078]],[[1047,1047],\\\"mapped\\\",[1079]],[[1048,1048],\\\"mapped\\\",[1080]],[[1049,1049],\\\"mapped\\\",[1081]],[[1050,1050],\\\"mapped\\\",[1082]],[[1051,1051],\\\"mapped\\\",[1083]],[[1052,1052],\\\"mapped\\\",[1084]],[[1053,1053],\\\"mapped\\\",[1085]],[[1054,1054],\\\"mapped\\\",[1086]],[[1055,1055],\\\"mapped\\\",[1087]],[[1056,1056],\\\"mapped\\\",[1088]],[[1057,1057],\\\"mapped\\\",[1089]],[[1058,1058],\\\"mapped\\\",[1090]],[[1059,1059],\\\"mapped\\\",[1091]],[[1060,1060],\\\"mapped\\\",[1092]],[[1061,1061],\\\"mapped\\\",[1093]],[[1062,1062],\\\"mapped\\\",[1094]],[[1063,1063],\\\"mapped\\\",[1095]],[[1064,1064],\\\"mapped\\\",[1096]],[[1065,1065],\\\"mapped\\\",[1097]],[[1066,1066],\\\"mapped\\\",[1098]],[[1067,1067],\\\"mapped\\\",[1099]],[[1068,1068],\\\"mapped\\\",[1100]],[[1069,1069],\\\"mapped\\\",[1101]],[[1070,1070],\\\"mapped\\\",[1102]],[[1071,1071],\\\"mapped\\\",[1103]],[[1072,1103],\\\"valid\\\"],[[1104,1104],\\\"valid\\\"],[[1105,1116],\\\"valid\\\"],[[1117,1117],\\\"valid\\\"],[[1118,1119],\\\"valid\\\"],[[1120,1120],\\\"mapped\\\",[1121]],[[1121,1121],\\\"valid\\\"],[[1122,1122],\\\"mapped\\\",[1123]],[[1123,1123],\\\"valid\\\"],[[1124,1124],\\\"mapped\\\",[1125]],[[1125,1125],\\\"valid\\\"],[[1126,1126],\\\"mapped\\\",[1127]],[[1127,1127],\\\"valid\\\"],[[1128,1128],\\\"mapped\\\",[1129]],[[1129,1129],\\\"valid\\\"],[[1130,1130],\\\"mapped\\\",[1131]],[[1131,1131],\\\"valid\\\"],[[1132,1132],\\\"mapped\\\",[1133]],[[1133,1133],\\\"valid\\\"],[[1134,1134],\\\"mapped\\\",[1135]],[[1135,1135],\\\"valid\\\"],[[1136,1136],\\\"mapped\\\",[1137]],[[1137,1137],\\\"valid\\\"],[[1138,1138],\\\"mapped\\\",[1139]],[[1139,1139],\\\"valid\\\"],[[1140,1140],\\\"mapped\\\",[1141]],[[1141,1141],\\\"valid\\\"],[[1142,1142],\\\"mapped\\\",[1143]],[[1143,1143],\\\"valid\\\"],[[1144,1144],\\\"mapped\\\",[1145]],[[1145,1145],\\\"valid\\\"],[[1146,1146],\\\"mapped\\\",[1147]],[[1147,1147],\\\"valid\\\"],[[1148,1148],\\\"mapped\\\",[1149]],[[1149,1149],\\\"valid\\\"],[[1150,1150],\\\"mapped\\\",[1151]],[[1151,1151],\\\"valid\\\"],[[1152,1152],\\\"mapped\\\",[1153]],[[1153,1153],\\\"valid\\\"],[[1154,1154],\\\"valid\\\",[],\\\"NV8\\\"],[[1155,1158],\\\"valid\\\"],[[1159,1159],\\\"valid\\\"],[[1160,1161],\\\"valid\\\",[],\\\"NV8\\\"],[[1162,1162],\\\"mapped\\\",[1163]],[[1163,1163],\\\"valid\\\"],[[1164,1164],\\\"mapped\\\",[1165]],[[1165,1165],\\\"valid\\\"],[[1166,1166],\\\"mapped\\\",[1167]],[[1167,1167],\\\"valid\\\"],[[1168,1168],\\\"mapped\\\",[1169]],[[1169,1169],\\\"valid\\\"],[[1170,1170],\\\"mapped\\\",[1171]],[[1171,1171],\\\"valid\\\"],[[1172,1172],\\\"mapped\\\",[1173]],[[1173,1173],\\\"valid\\\"],[[1174,1174],\\\"mapped\\\",[1175]],[[1175,1175],\\\"valid\\\"],[[1176,1176],\\\"mapped\\\",[1177]],[[1177,1177],\\\"valid\\\"],[[1178,1178],\\\"mapped\\\",[1179]],[[1179,1179],\\\"valid\\\"],[[1180,1180],\\\"mapped\\\",[1181]],[[1181,1181],\\\"valid\\\"],[[1182,1182],\\\"mapped\\\",[1183]],[[1183,1183],\\\"valid\\\"],[[1184,1184],\\\"mapped\\\",[1185]],[[1185,1185],\\\"valid\\\"],[[1186,1186],\\\"mapped\\\",[1187]],[[1187,1187],\\\"valid\\\"],[[1188,1188],\\\"mapped\\\",[1189]],[[1189,1189],\\\"valid\\\"],[[1190,1190],\\\"mapped\\\",[1191]],[[1191,1191],\\\"valid\\\"],[[1192,1192],\\\"mapped\\\",[1193]],[[1193,1193],\\\"valid\\\"],[[1194,1194],\\\"mapped\\\",[1195]],[[1195,1195],\\\"valid\\\"],[[1196,1196],\\\"mapped\\\",[1197]],[[1197,1197],\\\"valid\\\"],[[1198,1198],\\\"mapped\\\",[1199]],[[1199,1199],\\\"valid\\\"],[[1200,1200],\\\"mapped\\\",[1201]],[[1201,1201],\\\"valid\\\"],[[1202,1202],\\\"mapped\\\",[1203]],[[1203,1203],\\\"valid\\\"],[[1204,1204],\\\"mapped\\\",[1205]],[[1205,1205],\\\"valid\\\"],[[1206,1206],\\\"mapped\\\",[1207]],[[1207,1207],\\\"valid\\\"],[[1208,1208],\\\"mapped\\\",[1209]],[[1209,1209],\\\"valid\\\"],[[1210,1210],\\\"mapped\\\",[1211]],[[1211,1211],\\\"valid\\\"],[[1212,1212],\\\"mapped\\\",[1213]],[[1213,1213],\\\"valid\\\"],[[1214,1214],\\\"mapped\\\",[1215]],[[1215,1215],\\\"valid\\\"],[[1216,1216],\\\"disallowed\\\"],[[1217,1217],\\\"mapped\\\",[1218]],[[1218,1218],\\\"valid\\\"],[[1219,1219],\\\"mapped\\\",[1220]],[[1220,1220],\\\"valid\\\"],[[1221,1221],\\\"mapped\\\",[1222]],[[1222,1222],\\\"valid\\\"],[[1223,1223],\\\"mapped\\\",[1224]],[[1224,1224],\\\"valid\\\"],[[1225,1225],\\\"mapped\\\",[1226]],[[1226,1226],\\\"valid\\\"],[[1227,1227],\\\"mapped\\\",[1228]],[[1228,1228],\\\"valid\\\"],[[1229,1229],\\\"mapped\\\",[1230]],[[1230,1230],\\\"valid\\\"],[[1231,1231],\\\"valid\\\"],[[1232,1232],\\\"mapped\\\",[1233]],[[1233,1233],\\\"valid\\\"],[[1234,1234],\\\"mapped\\\",[1235]],[[1235,1235],\\\"valid\\\"],[[1236,1236],\\\"mapped\\\",[1237]],[[1237,1237],\\\"valid\\\"],[[1238,1238],\\\"mapped\\\",[1239]],[[1239,1239],\\\"valid\\\"],[[1240,1240],\\\"mapped\\\",[1241]],[[1241,1241],\\\"valid\\\"],[[1242,1242],\\\"mapped\\\",[1243]],[[1243,1243],\\\"valid\\\"],[[1244,1244],\\\"mapped\\\",[1245]],[[1245,1245],\\\"valid\\\"],[[1246,1246],\\\"mapped\\\",[1247]],[[1247,1247],\\\"valid\\\"],[[1248,1248],\\\"mapped\\\",[1249]],[[1249,1249],\\\"valid\\\"],[[1250,1250],\\\"mapped\\\",[1251]],[[1251,1251],\\\"valid\\\"],[[1252,1252],\\\"mapped\\\",[1253]],[[1253,1253],\\\"valid\\\"],[[1254,1254],\\\"mapped\\\",[1255]],[[1255,1255],\\\"valid\\\"],[[1256,1256],\\\"mapped\\\",[1257]],[[1257,1257],\\\"valid\\\"],[[1258,1258],\\\"mapped\\\",[1259]],[[1259,1259],\\\"valid\\\"],[[1260,1260],\\\"mapped\\\",[1261]],[[1261,1261],\\\"valid\\\"],[[1262,1262],\\\"mapped\\\",[1263]],[[1263,1263],\\\"valid\\\"],[[1264,1264],\\\"mapped\\\",[1265]],[[1265,1265],\\\"valid\\\"],[[1266,1266],\\\"mapped\\\",[1267]],[[1267,1267],\\\"valid\\\"],[[1268,1268],\\\"mapped\\\",[1269]],[[1269,1269],\\\"valid\\\"],[[1270,1270],\\\"mapped\\\",[1271]],[[1271,1271],\\\"valid\\\"],[[1272,1272],\\\"mapped\\\",[1273]],[[1273,1273],\\\"valid\\\"],[[1274,1274],\\\"mapped\\\",[1275]],[[1275,1275],\\\"valid\\\"],[[1276,1276],\\\"mapped\\\",[1277]],[[1277,1277],\\\"valid\\\"],[[1278,1278],\\\"mapped\\\",[1279]],[[1279,1279],\\\"valid\\\"],[[1280,1280],\\\"mapped\\\",[1281]],[[1281,1281],\\\"valid\\\"],[[1282,1282],\\\"mapped\\\",[1283]],[[1283,1283],\\\"valid\\\"],[[1284,1284],\\\"mapped\\\",[1285]],[[1285,1285],\\\"valid\\\"],[[1286,1286],\\\"mapped\\\",[1287]],[[1287,1287],\\\"valid\\\"],[[1288,1288],\\\"mapped\\\",[1289]],[[1289,1289],\\\"valid\\\"],[[1290,1290],\\\"mapped\\\",[1291]],[[1291,1291],\\\"valid\\\"],[[1292,1292],\\\"mapped\\\",[1293]],[[1293,1293],\\\"valid\\\"],[[1294,1294],\\\"mapped\\\",[1295]],[[1295,1295],\\\"valid\\\"],[[1296,1296],\\\"mapped\\\",[1297]],[[1297,1297],\\\"valid\\\"],[[1298,1298],\\\"mapped\\\",[1299]],[[1299,1299],\\\"valid\\\"],[[1300,1300],\\\"mapped\\\",[1301]],[[1301,1301],\\\"valid\\\"],[[1302,1302],\\\"mapped\\\",[1303]],[[1303,1303],\\\"valid\\\"],[[1304,1304],\\\"mapped\\\",[1305]],[[1305,1305],\\\"valid\\\"],[[1306,1306],\\\"mapped\\\",[1307]],[[1307,1307],\\\"valid\\\"],[[1308,1308],\\\"mapped\\\",[1309]],[[1309,1309],\\\"valid\\\"],[[1310,1310],\\\"mapped\\\",[1311]],[[1311,1311],\\\"valid\\\"],[[1312,1312],\\\"mapped\\\",[1313]],[[1313,1313],\\\"valid\\\"],[[1314,1314],\\\"mapped\\\",[1315]],[[1315,1315],\\\"valid\\\"],[[1316,1316],\\\"mapped\\\",[1317]],[[1317,1317],\\\"valid\\\"],[[1318,1318],\\\"mapped\\\",[1319]],[[1319,1319],\\\"valid\\\"],[[1320,1320],\\\"mapped\\\",[1321]],[[1321,1321],\\\"valid\\\"],[[1322,1322],\\\"mapped\\\",[1323]],[[1323,1323],\\\"valid\\\"],[[1324,1324],\\\"mapped\\\",[1325]],[[1325,1325],\\\"valid\\\"],[[1326,1326],\\\"mapped\\\",[1327]],[[1327,1327],\\\"valid\\\"],[[1328,1328],\\\"disallowed\\\"],[[1329,1329],\\\"mapped\\\",[1377]],[[1330,1330],\\\"mapped\\\",[1378]],[[1331,1331],\\\"mapped\\\",[1379]],[[1332,1332],\\\"mapped\\\",[1380]],[[1333,1333],\\\"mapped\\\",[1381]],[[1334,1334],\\\"mapped\\\",[1382]],[[1335,1335],\\\"mapped\\\",[1383]],[[1336,1336],\\\"mapped\\\",[1384]],[[1337,1337],\\\"mapped\\\",[1385]],[[1338,1338],\\\"mapped\\\",[1386]],[[1339,1339],\\\"mapped\\\",[1387]],[[1340,1340],\\\"mapped\\\",[1388]],[[1341,1341],\\\"mapped\\\",[1389]],[[1342,1342],\\\"mapped\\\",[1390]],[[1343,1343],\\\"mapped\\\",[1391]],[[1344,1344],\\\"mapped\\\",[1392]],[[1345,1345],\\\"mapped\\\",[1393]],[[1346,1346],\\\"mapped\\\",[1394]],[[1347,1347],\\\"mapped\\\",[1395]],[[1348,1348],\\\"mapped\\\",[1396]],[[1349,1349],\\\"mapped\\\",[1397]],[[1350,1350],\\\"mapped\\\",[1398]],[[1351,1351],\\\"mapped\\\",[1399]],[[1352,1352],\\\"mapped\\\",[1400]],[[1353,1353],\\\"mapped\\\",[1401]],[[1354,1354],\\\"mapped\\\",[1402]],[[1355,1355],\\\"mapped\\\",[1403]],[[1356,1356],\\\"mapped\\\",[1404]],[[1357,1357],\\\"mapped\\\",[1405]],[[1358,1358],\\\"mapped\\\",[1406]],[[1359,1359],\\\"mapped\\\",[1407]],[[1360,1360],\\\"mapped\\\",[1408]],[[1361,1361],\\\"mapped\\\",[1409]],[[1362,1362],\\\"mapped\\\",[1410]],[[1363,1363],\\\"mapped\\\",[1411]],[[1364,1364],\\\"mapped\\\",[1412]],[[1365,1365],\\\"mapped\\\",[1413]],[[1366,1366],\\\"mapped\\\",[1414]],[[1367,1368],\\\"disallowed\\\"],[[1369,1369],\\\"valid\\\"],[[1370,1375],\\\"valid\\\",[],\\\"NV8\\\"],[[1376,1376],\\\"disallowed\\\"],[[1377,1414],\\\"valid\\\"],[[1415,1415],\\\"mapped\\\",[1381,1410]],[[1416,1416],\\\"disallowed\\\"],[[1417,1417],\\\"valid\\\",[],\\\"NV8\\\"],[[1418,1418],\\\"valid\\\",[],\\\"NV8\\\"],[[1419,1420],\\\"disallowed\\\"],[[1421,1422],\\\"valid\\\",[],\\\"NV8\\\"],[[1423,1423],\\\"valid\\\",[],\\\"NV8\\\"],[[1424,1424],\\\"disallowed\\\"],[[1425,1441],\\\"valid\\\"],[[1442,1442],\\\"valid\\\"],[[1443,1455],\\\"valid\\\"],[[1456,1465],\\\"valid\\\"],[[1466,1466],\\\"valid\\\"],[[1467,1469],\\\"valid\\\"],[[1470,1470],\\\"valid\\\",[],\\\"NV8\\\"],[[1471,1471],\\\"valid\\\"],[[1472,1472],\\\"valid\\\",[],\\\"NV8\\\"],[[1473,1474],\\\"valid\\\"],[[1475,1475],\\\"valid\\\",[],\\\"NV8\\\"],[[1476,1476],\\\"valid\\\"],[[1477,1477],\\\"valid\\\"],[[1478,1478],\\\"valid\\\",[],\\\"NV8\\\"],[[1479,1479],\\\"valid\\\"],[[1480,1487],\\\"disallowed\\\"],[[1488,1514],\\\"valid\\\"],[[1515,1519],\\\"disallowed\\\"],[[1520,1524],\\\"valid\\\"],[[1525,1535],\\\"disallowed\\\"],[[1536,1539],\\\"disallowed\\\"],[[1540,1540],\\\"disallowed\\\"],[[1541,1541],\\\"disallowed\\\"],[[1542,1546],\\\"valid\\\",[],\\\"NV8\\\"],[[1547,1547],\\\"valid\\\",[],\\\"NV8\\\"],[[1548,1548],\\\"valid\\\",[],\\\"NV8\\\"],[[1549,1551],\\\"valid\\\",[],\\\"NV8\\\"],[[1552,1557],\\\"valid\\\"],[[1558,1562],\\\"valid\\\"],[[1563,1563],\\\"valid\\\",[],\\\"NV8\\\"],[[1564,1564],\\\"disallowed\\\"],[[1565,1565],\\\"disallowed\\\"],[[1566,1566],\\\"valid\\\",[],\\\"NV8\\\"],[[1567,1567],\\\"valid\\\",[],\\\"NV8\\\"],[[1568,1568],\\\"valid\\\"],[[1569,1594],\\\"valid\\\"],[[1595,1599],\\\"valid\\\"],[[1600,1600],\\\"valid\\\",[],\\\"NV8\\\"],[[1601,1618],\\\"valid\\\"],[[1619,1621],\\\"valid\\\"],[[1622,1624],\\\"valid\\\"],[[1625,1630],\\\"valid\\\"],[[1631,1631],\\\"valid\\\"],[[1632,1641],\\\"valid\\\"],[[1642,1645],\\\"valid\\\",[],\\\"NV8\\\"],[[1646,1647],\\\"valid\\\"],[[1648,1652],\\\"valid\\\"],[[1653,1653],\\\"mapped\\\",[1575,1652]],[[1654,1654],\\\"mapped\\\",[1608,1652]],[[1655,1655],\\\"mapped\\\",[1735,1652]],[[1656,1656],\\\"mapped\\\",[1610,1652]],[[1657,1719],\\\"valid\\\"],[[1720,1721],\\\"valid\\\"],[[1722,1726],\\\"valid\\\"],[[1727,1727],\\\"valid\\\"],[[1728,1742],\\\"valid\\\"],[[1743,1743],\\\"valid\\\"],[[1744,1747],\\\"valid\\\"],[[1748,1748],\\\"valid\\\",[],\\\"NV8\\\"],[[1749,1756],\\\"valid\\\"],[[1757,1757],\\\"disallowed\\\"],[[1758,1758],\\\"valid\\\",[],\\\"NV8\\\"],[[1759,1768],\\\"valid\\\"],[[1769,1769],\\\"valid\\\",[],\\\"NV8\\\"],[[1770,1773],\\\"valid\\\"],[[1774,1775],\\\"valid\\\"],[[1776,1785],\\\"valid\\\"],[[1786,1790],\\\"valid\\\"],[[1791,1791],\\\"valid\\\"],[[1792,1805],\\\"valid\\\",[],\\\"NV8\\\"],[[1806,1806],\\\"disallowed\\\"],[[1807,1807],\\\"disallowed\\\"],[[1808,1836],\\\"valid\\\"],[[1837,1839],\\\"valid\\\"],[[1840,1866],\\\"valid\\\"],[[1867,1868],\\\"disallowed\\\"],[[1869,1871],\\\"valid\\\"],[[1872,1901],\\\"valid\\\"],[[1902,1919],\\\"valid\\\"],[[1920,1968],\\\"valid\\\"],[[1969,1969],\\\"valid\\\"],[[1970,1983],\\\"disallowed\\\"],[[1984,2037],\\\"valid\\\"],[[2038,2042],\\\"valid\\\",[],\\\"NV8\\\"],[[2043,2047],\\\"disallowed\\\"],[[2048,2093],\\\"valid\\\"],[[2094,2095],\\\"disallowed\\\"],[[2096,2110],\\\"valid\\\",[],\\\"NV8\\\"],[[2111,2111],\\\"disallowed\\\"],[[2112,2139],\\\"valid\\\"],[[2140,2141],\\\"disallowed\\\"],[[2142,2142],\\\"valid\\\",[],\\\"NV8\\\"],[[2143,2207],\\\"disallowed\\\"],[[2208,2208],\\\"valid\\\"],[[2209,2209],\\\"valid\\\"],[[2210,2220],\\\"valid\\\"],[[2221,2226],\\\"valid\\\"],[[2227,2228],\\\"valid\\\"],[[2229,2274],\\\"disallowed\\\"],[[2275,2275],\\\"valid\\\"],[[2276,2302],\\\"valid\\\"],[[2303,2303],\\\"valid\\\"],[[2304,2304],\\\"valid\\\"],[[2305,2307],\\\"valid\\\"],[[2308,2308],\\\"valid\\\"],[[2309,2361],\\\"valid\\\"],[[2362,2363],\\\"valid\\\"],[[2364,2381],\\\"valid\\\"],[[2382,2382],\\\"valid\\\"],[[2383,2383],\\\"valid\\\"],[[2384,2388],\\\"valid\\\"],[[2389,2389],\\\"valid\\\"],[[2390,2391],\\\"valid\\\"],[[2392,2392],\\\"mapped\\\",[2325,2364]],[[2393,2393],\\\"mapped\\\",[2326,2364]],[[2394,2394],\\\"mapped\\\",[2327,2364]],[[2395,2395],\\\"mapped\\\",[2332,2364]],[[2396,2396],\\\"mapped\\\",[2337,2364]],[[2397,2397],\\\"mapped\\\",[2338,2364]],[[2398,2398],\\\"mapped\\\",[2347,2364]],[[2399,2399],\\\"mapped\\\",[2351,2364]],[[2400,2403],\\\"valid\\\"],[[2404,2405],\\\"valid\\\",[],\\\"NV8\\\"],[[2406,2415],\\\"valid\\\"],[[2416,2416],\\\"valid\\\",[],\\\"NV8\\\"],[[2417,2418],\\\"valid\\\"],[[2419,2423],\\\"valid\\\"],[[2424,2424],\\\"valid\\\"],[[2425,2426],\\\"valid\\\"],[[2427,2428],\\\"valid\\\"],[[2429,2429],\\\"valid\\\"],[[2430,2431],\\\"valid\\\"],[[2432,2432],\\\"valid\\\"],[[2433,2435],\\\"valid\\\"],[[2436,2436],\\\"disallowed\\\"],[[2437,2444],\\\"valid\\\"],[[2445,2446],\\\"disallowed\\\"],[[2447,2448],\\\"valid\\\"],[[2449,2450],\\\"disallowed\\\"],[[2451,2472],\\\"valid\\\"],[[2473,2473],\\\"disallowed\\\"],[[2474,2480],\\\"valid\\\"],[[2481,2481],\\\"disallowed\\\"],[[2482,2482],\\\"valid\\\"],[[2483,2485],\\\"disallowed\\\"],[[2486,2489],\\\"valid\\\"],[[2490,2491],\\\"disallowed\\\"],[[2492,2492],\\\"valid\\\"],[[2493,2493],\\\"valid\\\"],[[2494,2500],\\\"valid\\\"],[[2501,2502],\\\"disallowed\\\"],[[2503,2504],\\\"valid\\\"],[[2505,2506],\\\"disallowed\\\"],[[2507,2509],\\\"valid\\\"],[[2510,2510],\\\"valid\\\"],[[2511,2518],\\\"disallowed\\\"],[[2519,2519],\\\"valid\\\"],[[2520,2523],\\\"disallowed\\\"],[[2524,2524],\\\"mapped\\\",[2465,2492]],[[2525,2525],\\\"mapped\\\",[2466,2492]],[[2526,2526],\\\"disallowed\\\"],[[2527,2527],\\\"mapped\\\",[2479,2492]],[[2528,2531],\\\"valid\\\"],[[2532,2533],\\\"disallowed\\\"],[[2534,2545],\\\"valid\\\"],[[2546,2554],\\\"valid\\\",[],\\\"NV8\\\"],[[2555,2555],\\\"valid\\\",[],\\\"NV8\\\"],[[2556,2560],\\\"disallowed\\\"],[[2561,2561],\\\"valid\\\"],[[2562,2562],\\\"valid\\\"],[[2563,2563],\\\"valid\\\"],[[2564,2564],\\\"disallowed\\\"],[[2565,2570],\\\"valid\\\"],[[2571,2574],\\\"disallowed\\\"],[[2575,2576],\\\"valid\\\"],[[2577,2578],\\\"disallowed\\\"],[[2579,2600],\\\"valid\\\"],[[2601,2601],\\\"disallowed\\\"],[[2602,2608],\\\"valid\\\"],[[2609,2609],\\\"disallowed\\\"],[[2610,2610],\\\"valid\\\"],[[2611,2611],\\\"mapped\\\",[2610,2620]],[[2612,2612],\\\"disallowed\\\"],[[2613,2613],\\\"valid\\\"],[[2614,2614],\\\"mapped\\\",[2616,2620]],[[2615,2615],\\\"disallowed\\\"],[[2616,2617],\\\"valid\\\"],[[2618,2619],\\\"disallowed\\\"],[[2620,2620],\\\"valid\\\"],[[2621,2621],\\\"disallowed\\\"],[[2622,2626],\\\"valid\\\"],[[2627,2630],\\\"disallowed\\\"],[[2631,2632],\\\"valid\\\"],[[2633,2634],\\\"disallowed\\\"],[[2635,2637],\\\"valid\\\"],[[2638,2640],\\\"disallowed\\\"],[[2641,2641],\\\"valid\\\"],[[2642,2648],\\\"disallowed\\\"],[[2649,2649],\\\"mapped\\\",[2582,2620]],[[2650,2650],\\\"mapped\\\",[2583,2620]],[[2651,2651],\\\"mapped\\\",[2588,2620]],[[2652,2652],\\\"valid\\\"],[[2653,2653],\\\"disallowed\\\"],[[2654,2654],\\\"mapped\\\",[2603,2620]],[[2655,2661],\\\"disallowed\\\"],[[2662,2676],\\\"valid\\\"],[[2677,2677],\\\"valid\\\"],[[2678,2688],\\\"disallowed\\\"],[[2689,2691],\\\"valid\\\"],[[2692,2692],\\\"disallowed\\\"],[[2693,2699],\\\"valid\\\"],[[2700,2700],\\\"valid\\\"],[[2701,2701],\\\"valid\\\"],[[2702,2702],\\\"disallowed\\\"],[[2703,2705],\\\"valid\\\"],[[2706,2706],\\\"disallowed\\\"],[[2707,2728],\\\"valid\\\"],[[2729,2729],\\\"disallowed\\\"],[[2730,2736],\\\"valid\\\"],[[2737,2737],\\\"disallowed\\\"],[[2738,2739],\\\"valid\\\"],[[2740,2740],\\\"disallowed\\\"],[[2741,2745],\\\"valid\\\"],[[2746,2747],\\\"disallowed\\\"],[[2748,2757],\\\"valid\\\"],[[2758,2758],\\\"disallowed\\\"],[[2759,2761],\\\"valid\\\"],[[2762,2762],\\\"disallowed\\\"],[[2763,2765],\\\"valid\\\"],[[2766,2767],\\\"disallowed\\\"],[[2768,2768],\\\"valid\\\"],[[2769,2783],\\\"disallowed\\\"],[[2784,2784],\\\"valid\\\"],[[2785,2787],\\\"valid\\\"],[[2788,2789],\\\"disallowed\\\"],[[2790,2799],\\\"valid\\\"],[[2800,2800],\\\"valid\\\",[],\\\"NV8\\\"],[[2801,2801],\\\"valid\\\",[],\\\"NV8\\\"],[[2802,2808],\\\"disallowed\\\"],[[2809,2809],\\\"valid\\\"],[[2810,2816],\\\"disallowed\\\"],[[2817,2819],\\\"valid\\\"],[[2820,2820],\\\"disallowed\\\"],[[2821,2828],\\\"valid\\\"],[[2829,2830],\\\"disallowed\\\"],[[2831,2832],\\\"valid\\\"],[[2833,2834],\\\"disallowed\\\"],[[2835,2856],\\\"valid\\\"],[[2857,2857],\\\"disallowed\\\"],[[2858,2864],\\\"valid\\\"],[[2865,2865],\\\"disallowed\\\"],[[2866,2867],\\\"valid\\\"],[[2868,2868],\\\"disallowed\\\"],[[2869,2869],\\\"valid\\\"],[[2870,2873],\\\"valid\\\"],[[2874,2875],\\\"disallowed\\\"],[[2876,2883],\\\"valid\\\"],[[2884,2884],\\\"valid\\\"],[[2885,2886],\\\"disallowed\\\"],[[2887,2888],\\\"valid\\\"],[[2889,2890],\\\"disallowed\\\"],[[2891,2893],\\\"valid\\\"],[[2894,2901],\\\"disallowed\\\"],[[2902,2903],\\\"valid\\\"],[[2904,2907],\\\"disallowed\\\"],[[2908,2908],\\\"mapped\\\",[2849,2876]],[[2909,2909],\\\"mapped\\\",[2850,2876]],[[2910,2910],\\\"disallowed\\\"],[[2911,2913],\\\"valid\\\"],[[2914,2915],\\\"valid\\\"],[[2916,2917],\\\"disallowed\\\"],[[2918,2927],\\\"valid\\\"],[[2928,2928],\\\"valid\\\",[],\\\"NV8\\\"],[[2929,2929],\\\"valid\\\"],[[2930,2935],\\\"valid\\\",[],\\\"NV8\\\"],[[2936,2945],\\\"disallowed\\\"],[[2946,2947],\\\"valid\\\"],[[2948,2948],\\\"disallowed\\\"],[[2949,2954],\\\"valid\\\"],[[2955,2957],\\\"disallowed\\\"],[[2958,2960],\\\"valid\\\"],[[2961,2961],\\\"disallowed\\\"],[[2962,2965],\\\"valid\\\"],[[2966,2968],\\\"disallowed\\\"],[[2969,2970],\\\"valid\\\"],[[2971,2971],\\\"disallowed\\\"],[[2972,2972],\\\"valid\\\"],[[2973,2973],\\\"disallowed\\\"],[[2974,2975],\\\"valid\\\"],[[2976,2978],\\\"disallowed\\\"],[[2979,2980],\\\"valid\\\"],[[2981,2983],\\\"disallowed\\\"],[[2984,2986],\\\"valid\\\"],[[2987,2989],\\\"disallowed\\\"],[[2990,2997],\\\"valid\\\"],[[2998,2998],\\\"valid\\\"],[[2999,3001],\\\"valid\\\"],[[3002,3005],\\\"disallowed\\\"],[[3006,3010],\\\"valid\\\"],[[3011,3013],\\\"disallowed\\\"],[[3014,3016],\\\"valid\\\"],[[3017,3017],\\\"disallowed\\\"],[[3018,3021],\\\"valid\\\"],[[3022,3023],\\\"disallowed\\\"],[[3024,3024],\\\"valid\\\"],[[3025,3030],\\\"disallowed\\\"],[[3031,3031],\\\"valid\\\"],[[3032,3045],\\\"disallowed\\\"],[[3046,3046],\\\"valid\\\"],[[3047,3055],\\\"valid\\\"],[[3056,3058],\\\"valid\\\",[],\\\"NV8\\\"],[[3059,3066],\\\"valid\\\",[],\\\"NV8\\\"],[[3067,3071],\\\"disallowed\\\"],[[3072,3072],\\\"valid\\\"],[[3073,3075],\\\"valid\\\"],[[3076,3076],\\\"disallowed\\\"],[[3077,3084],\\\"valid\\\"],[[3085,3085],\\\"disallowed\\\"],[[3086,3088],\\\"valid\\\"],[[3089,3089],\\\"disallowed\\\"],[[3090,3112],\\\"valid\\\"],[[3113,3113],\\\"disallowed\\\"],[[3114,3123],\\\"valid\\\"],[[3124,3124],\\\"valid\\\"],[[3125,3129],\\\"valid\\\"],[[3130,3132],\\\"disallowed\\\"],[[3133,3133],\\\"valid\\\"],[[3134,3140],\\\"valid\\\"],[[3141,3141],\\\"disallowed\\\"],[[3142,3144],\\\"valid\\\"],[[3145,3145],\\\"disallowed\\\"],[[3146,3149],\\\"valid\\\"],[[3150,3156],\\\"disallowed\\\"],[[3157,3158],\\\"valid\\\"],[[3159,3159],\\\"disallowed\\\"],[[3160,3161],\\\"valid\\\"],[[3162,3162],\\\"valid\\\"],[[3163,3167],\\\"disallowed\\\"],[[3168,3169],\\\"valid\\\"],[[3170,3171],\\\"valid\\\"],[[3172,3173],\\\"disallowed\\\"],[[3174,3183],\\\"valid\\\"],[[3184,3191],\\\"disallowed\\\"],[[3192,3199],\\\"valid\\\",[],\\\"NV8\\\"],[[3200,3200],\\\"disallowed\\\"],[[3201,3201],\\\"valid\\\"],[[3202,3203],\\\"valid\\\"],[[3204,3204],\\\"disallowed\\\"],[[3205,3212],\\\"valid\\\"],[[3213,3213],\\\"disallowed\\\"],[[3214,3216],\\\"valid\\\"],[[3217,3217],\\\"disallowed\\\"],[[3218,3240],\\\"valid\\\"],[[3241,3241],\\\"disallowed\\\"],[[3242,3251],\\\"valid\\\"],[[3252,3252],\\\"disallowed\\\"],[[3253,3257],\\\"valid\\\"],[[3258,3259],\\\"disallowed\\\"],[[3260,3261],\\\"valid\\\"],[[3262,3268],\\\"valid\\\"],[[3269,3269],\\\"disallowed\\\"],[[3270,3272],\\\"valid\\\"],[[3273,3273],\\\"disallowed\\\"],[[3274,3277],\\\"valid\\\"],[[3278,3284],\\\"disallowed\\\"],[[3285,3286],\\\"valid\\\"],[[3287,3293],\\\"disallowed\\\"],[[3294,3294],\\\"valid\\\"],[[3295,3295],\\\"disallowed\\\"],[[3296,3297],\\\"valid\\\"],[[3298,3299],\\\"valid\\\"],[[3300,3301],\\\"disallowed\\\"],[[3302,3311],\\\"valid\\\"],[[3312,3312],\\\"disallowed\\\"],[[3313,3314],\\\"valid\\\"],[[3315,3328],\\\"disallowed\\\"],[[3329,3329],\\\"valid\\\"],[[3330,3331],\\\"valid\\\"],[[3332,3332],\\\"disallowed\\\"],[[3333,3340],\\\"valid\\\"],[[3341,3341],\\\"disallowed\\\"],[[3342,3344],\\\"valid\\\"],[[3345,3345],\\\"disallowed\\\"],[[3346,3368],\\\"valid\\\"],[[3369,3369],\\\"valid\\\"],[[3370,3385],\\\"valid\\\"],[[3386,3386],\\\"valid\\\"],[[3387,3388],\\\"disallowed\\\"],[[3389,3389],\\\"valid\\\"],[[3390,3395],\\\"valid\\\"],[[3396,3396],\\\"valid\\\"],[[3397,3397],\\\"disallowed\\\"],[[3398,3400],\\\"valid\\\"],[[3401,3401],\\\"disallowed\\\"],[[3402,3405],\\\"valid\\\"],[[3406,3406],\\\"valid\\\"],[[3407,3414],\\\"disallowed\\\"],[[3415,3415],\\\"valid\\\"],[[3416,3422],\\\"disallowed\\\"],[[3423,3423],\\\"valid\\\"],[[3424,3425],\\\"valid\\\"],[[3426,3427],\\\"valid\\\"],[[3428,3429],\\\"disallowed\\\"],[[3430,3439],\\\"valid\\\"],[[3440,3445],\\\"valid\\\",[],\\\"NV8\\\"],[[3446,3448],\\\"disallowed\\\"],[[3449,3449],\\\"valid\\\",[],\\\"NV8\\\"],[[3450,3455],\\\"valid\\\"],[[3456,3457],\\\"disallowed\\\"],[[3458,3459],\\\"valid\\\"],[[3460,3460],\\\"disallowed\\\"],[[3461,3478],\\\"valid\\\"],[[3479,3481],\\\"disallowed\\\"],[[3482,3505],\\\"valid\\\"],[[3506,3506],\\\"disallowed\\\"],[[3507,3515],\\\"valid\\\"],[[3516,3516],\\\"disallowed\\\"],[[3517,3517],\\\"valid\\\"],[[3518,3519],\\\"disallowed\\\"],[[3520,3526],\\\"valid\\\"],[[3527,3529],\\\"disallowed\\\"],[[3530,3530],\\\"valid\\\"],[[3531,3534],\\\"disallowed\\\"],[[3535,3540],\\\"valid\\\"],[[3541,3541],\\\"disallowed\\\"],[[3542,3542],\\\"valid\\\"],[[3543,3543],\\\"disallowed\\\"],[[3544,3551],\\\"valid\\\"],[[3552,3557],\\\"disallowed\\\"],[[3558,3567],\\\"valid\\\"],[[3568,3569],\\\"disallowed\\\"],[[3570,3571],\\\"valid\\\"],[[3572,3572],\\\"valid\\\",[],\\\"NV8\\\"],[[3573,3584],\\\"disallowed\\\"],[[3585,3634],\\\"valid\\\"],[[3635,3635],\\\"mapped\\\",[3661,3634]],[[3636,3642],\\\"valid\\\"],[[3643,3646],\\\"disallowed\\\"],[[3647,3647],\\\"valid\\\",[],\\\"NV8\\\"],[[3648,3662],\\\"valid\\\"],[[3663,3663],\\\"valid\\\",[],\\\"NV8\\\"],[[3664,3673],\\\"valid\\\"],[[3674,3675],\\\"valid\\\",[],\\\"NV8\\\"],[[3676,3712],\\\"disallowed\\\"],[[3713,3714],\\\"valid\\\"],[[3715,3715],\\\"disallowed\\\"],[[3716,3716],\\\"valid\\\"],[[3717,3718],\\\"disallowed\\\"],[[3719,3720],\\\"valid\\\"],[[3721,3721],\\\"disallowed\\\"],[[3722,3722],\\\"valid\\\"],[[3723,3724],\\\"disallowed\\\"],[[3725,3725],\\\"valid\\\"],[[3726,3731],\\\"disallowed\\\"],[[3732,3735],\\\"valid\\\"],[[3736,3736],\\\"disallowed\\\"],[[3737,3743],\\\"valid\\\"],[[3744,3744],\\\"disallowed\\\"],[[3745,3747],\\\"valid\\\"],[[3748,3748],\\\"disallowed\\\"],[[3749,3749],\\\"valid\\\"],[[3750,3750],\\\"disallowed\\\"],[[3751,3751],\\\"valid\\\"],[[3752,3753],\\\"disallowed\\\"],[[3754,3755],\\\"valid\\\"],[[3756,3756],\\\"disallowed\\\"],[[3757,3762],\\\"valid\\\"],[[3763,3763],\\\"mapped\\\",[3789,3762]],[[3764,3769],\\\"valid\\\"],[[3770,3770],\\\"disallowed\\\"],[[3771,3773],\\\"valid\\\"],[[3774,3775],\\\"disallowed\\\"],[[3776,3780],\\\"valid\\\"],[[3781,3781],\\\"disallowed\\\"],[[3782,3782],\\\"valid\\\"],[[3783,3783],\\\"disallowed\\\"],[[3784,3789],\\\"valid\\\"],[[3790,3791],\\\"disallowed\\\"],[[3792,3801],\\\"valid\\\"],[[3802,3803],\\\"disallowed\\\"],[[3804,3804],\\\"mapped\\\",[3755,3737]],[[3805,3805],\\\"mapped\\\",[3755,3745]],[[3806,3807],\\\"valid\\\"],[[3808,3839],\\\"disallowed\\\"],[[3840,3840],\\\"valid\\\"],[[3841,3850],\\\"valid\\\",[],\\\"NV8\\\"],[[3851,3851],\\\"valid\\\"],[[3852,3852],\\\"mapped\\\",[3851]],[[3853,3863],\\\"valid\\\",[],\\\"NV8\\\"],[[3864,3865],\\\"valid\\\"],[[3866,3871],\\\"valid\\\",[],\\\"NV8\\\"],[[3872,3881],\\\"valid\\\"],[[3882,3892],\\\"valid\\\",[],\\\"NV8\\\"],[[3893,3893],\\\"valid\\\"],[[3894,3894],\\\"valid\\\",[],\\\"NV8\\\"],[[3895,3895],\\\"valid\\\"],[[3896,3896],\\\"valid\\\",[],\\\"NV8\\\"],[[3897,3897],\\\"valid\\\"],[[3898,3901],\\\"valid\\\",[],\\\"NV8\\\"],[[3902,3906],\\\"valid\\\"],[[3907,3907],\\\"mapped\\\",[3906,4023]],[[3908,3911],\\\"valid\\\"],[[3912,3912],\\\"disallowed\\\"],[[3913,3916],\\\"valid\\\"],[[3917,3917],\\\"mapped\\\",[3916,4023]],[[3918,3921],\\\"valid\\\"],[[3922,3922],\\\"mapped\\\",[3921,4023]],[[3923,3926],\\\"valid\\\"],[[3927,3927],\\\"mapped\\\",[3926,4023]],[[3928,3931],\\\"valid\\\"],[[3932,3932],\\\"mapped\\\",[3931,4023]],[[3933,3944],\\\"valid\\\"],[[3945,3945],\\\"mapped\\\",[3904,4021]],[[3946,3946],\\\"valid\\\"],[[3947,3948],\\\"valid\\\"],[[3949,3952],\\\"disallowed\\\"],[[3953,3954],\\\"valid\\\"],[[3955,3955],\\\"mapped\\\",[3953,3954]],[[3956,3956],\\\"valid\\\"],[[3957,3957],\\\"mapped\\\",[3953,3956]],[[3958,3958],\\\"mapped\\\",[4018,3968]],[[3959,3959],\\\"mapped\\\",[4018,3953,3968]],[[3960,3960],\\\"mapped\\\",[4019,3968]],[[3961,3961],\\\"mapped\\\",[4019,3953,3968]],[[3962,3968],\\\"valid\\\"],[[3969,3969],\\\"mapped\\\",[3953,3968]],[[3970,3972],\\\"valid\\\"],[[3973,3973],\\\"valid\\\",[],\\\"NV8\\\"],[[3974,3979],\\\"valid\\\"],[[3980,3983],\\\"valid\\\"],[[3984,3986],\\\"valid\\\"],[[3987,3987],\\\"mapped\\\",[3986,4023]],[[3988,3989],\\\"valid\\\"],[[3990,3990],\\\"valid\\\"],[[3991,3991],\\\"valid\\\"],[[3992,3992],\\\"disallowed\\\"],[[3993,3996],\\\"valid\\\"],[[3997,3997],\\\"mapped\\\",[3996,4023]],[[3998,4001],\\\"valid\\\"],[[4002,4002],\\\"mapped\\\",[4001,4023]],[[4003,4006],\\\"valid\\\"],[[4007,4007],\\\"mapped\\\",[4006,4023]],[[4008,4011],\\\"valid\\\"],[[4012,4012],\\\"mapped\\\",[4011,4023]],[[4013,4013],\\\"valid\\\"],[[4014,4016],\\\"valid\\\"],[[4017,4023],\\\"valid\\\"],[[4024,4024],\\\"valid\\\"],[[4025,4025],\\\"mapped\\\",[3984,4021]],[[4026,4028],\\\"valid\\\"],[[4029,4029],\\\"disallowed\\\"],[[4030,4037],\\\"valid\\\",[],\\\"NV8\\\"],[[4038,4038],\\\"valid\\\"],[[4039,4044],\\\"valid\\\",[],\\\"NV8\\\"],[[4045,4045],\\\"disallowed\\\"],[[4046,4046],\\\"valid\\\",[],\\\"NV8\\\"],[[4047,4047],\\\"valid\\\",[],\\\"NV8\\\"],[[4048,4049],\\\"valid\\\",[],\\\"NV8\\\"],[[4050,4052],\\\"valid\\\",[],\\\"NV8\\\"],[[4053,4056],\\\"valid\\\",[],\\\"NV8\\\"],[[4057,4058],\\\"valid\\\",[],\\\"NV8\\\"],[[4059,4095],\\\"disallowed\\\"],[[4096,4129],\\\"valid\\\"],[[4130,4130],\\\"valid\\\"],[[4131,4135],\\\"valid\\\"],[[4136,4136],\\\"valid\\\"],[[4137,4138],\\\"valid\\\"],[[4139,4139],\\\"valid\\\"],[[4140,4146],\\\"valid\\\"],[[4147,4149],\\\"valid\\\"],[[4150,4153],\\\"valid\\\"],[[4154,4159],\\\"valid\\\"],[[4160,4169],\\\"valid\\\"],[[4170,4175],\\\"valid\\\",[],\\\"NV8\\\"],[[4176,4185],\\\"valid\\\"],[[4186,4249],\\\"valid\\\"],[[4250,4253],\\\"valid\\\"],[[4254,4255],\\\"valid\\\",[],\\\"NV8\\\"],[[4256,4293],\\\"disallowed\\\"],[[4294,4294],\\\"disallowed\\\"],[[4295,4295],\\\"mapped\\\",[11559]],[[4296,4300],\\\"disallowed\\\"],[[4301,4301],\\\"mapped\\\",[11565]],[[4302,4303],\\\"disallowed\\\"],[[4304,4342],\\\"valid\\\"],[[4343,4344],\\\"valid\\\"],[[4345,4346],\\\"valid\\\"],[[4347,4347],\\\"valid\\\",[],\\\"NV8\\\"],[[4348,4348],\\\"mapped\\\",[4316]],[[4349,4351],\\\"valid\\\"],[[4352,4441],\\\"valid\\\",[],\\\"NV8\\\"],[[4442,4446],\\\"valid\\\",[],\\\"NV8\\\"],[[4447,4448],\\\"disallowed\\\"],[[4449,4514],\\\"valid\\\",[],\\\"NV8\\\"],[[4515,4519],\\\"valid\\\",[],\\\"NV8\\\"],[[4520,4601],\\\"valid\\\",[],\\\"NV8\\\"],[[4602,4607],\\\"valid\\\",[],\\\"NV8\\\"],[[4608,4614],\\\"valid\\\"],[[4615,4615],\\\"valid\\\"],[[4616,4678],\\\"valid\\\"],[[4679,4679],\\\"valid\\\"],[[4680,4680],\\\"valid\\\"],[[4681,4681],\\\"disallowed\\\"],[[4682,4685],\\\"valid\\\"],[[4686,4687],\\\"disallowed\\\"],[[4688,4694],\\\"valid\\\"],[[4695,4695],\\\"disallowed\\\"],[[4696,4696],\\\"valid\\\"],[[4697,4697],\\\"disallowed\\\"],[[4698,4701],\\\"valid\\\"],[[4702,4703],\\\"disallowed\\\"],[[4704,4742],\\\"valid\\\"],[[4743,4743],\\\"valid\\\"],[[4744,4744],\\\"valid\\\"],[[4745,4745],\\\"disallowed\\\"],[[4746,4749],\\\"valid\\\"],[[4750,4751],\\\"disallowed\\\"],[[4752,4782],\\\"valid\\\"],[[4783,4783],\\\"valid\\\"],[[4784,4784],\\\"valid\\\"],[[4785,4785],\\\"disallowed\\\"],[[4786,4789],\\\"valid\\\"],[[4790,4791],\\\"disallowed\\\"],[[4792,4798],\\\"valid\\\"],[[4799,4799],\\\"disallowed\\\"],[[4800,4800],\\\"valid\\\"],[[4801,4801],\\\"disallowed\\\"],[[4802,4805],\\\"valid\\\"],[[4806,4807],\\\"disallowed\\\"],[[4808,4814],\\\"valid\\\"],[[4815,4815],\\\"valid\\\"],[[4816,4822],\\\"valid\\\"],[[4823,4823],\\\"disallowed\\\"],[[4824,4846],\\\"valid\\\"],[[4847,4847],\\\"valid\\\"],[[4848,4878],\\\"valid\\\"],[[4879,4879],\\\"valid\\\"],[[4880,4880],\\\"valid\\\"],[[4881,4881],\\\"disallowed\\\"],[[4882,4885],\\\"valid\\\"],[[4886,4887],\\\"disallowed\\\"],[[4888,4894],\\\"valid\\\"],[[4895,4895],\\\"valid\\\"],[[4896,4934],\\\"valid\\\"],[[4935,4935],\\\"valid\\\"],[[4936,4954],\\\"valid\\\"],[[4955,4956],\\\"disallowed\\\"],[[4957,4958],\\\"valid\\\"],[[4959,4959],\\\"valid\\\"],[[4960,4960],\\\"valid\\\",[],\\\"NV8\\\"],[[4961,4988],\\\"valid\\\",[],\\\"NV8\\\"],[[4989,4991],\\\"disallowed\\\"],[[4992,5007],\\\"valid\\\"],[[5008,5017],\\\"valid\\\",[],\\\"NV8\\\"],[[5018,5023],\\\"disallowed\\\"],[[5024,5108],\\\"valid\\\"],[[5109,5109],\\\"valid\\\"],[[5110,5111],\\\"disallowed\\\"],[[5112,5112],\\\"mapped\\\",[5104]],[[5113,5113],\\\"mapped\\\",[5105]],[[5114,5114],\\\"mapped\\\",[5106]],[[5115,5115],\\\"mapped\\\",[5107]],[[5116,5116],\\\"mapped\\\",[5108]],[[5117,5117],\\\"mapped\\\",[5109]],[[5118,5119],\\\"disallowed\\\"],[[5120,5120],\\\"valid\\\",[],\\\"NV8\\\"],[[5121,5740],\\\"valid\\\"],[[5741,5742],\\\"valid\\\",[],\\\"NV8\\\"],[[5743,5750],\\\"valid\\\"],[[5751,5759],\\\"valid\\\"],[[5760,5760],\\\"disallowed\\\"],[[5761,5786],\\\"valid\\\"],[[5787,5788],\\\"valid\\\",[],\\\"NV8\\\"],[[5789,5791],\\\"disallowed\\\"],[[5792,5866],\\\"valid\\\"],[[5867,5872],\\\"valid\\\",[],\\\"NV8\\\"],[[5873,5880],\\\"valid\\\"],[[5881,5887],\\\"disallowed\\\"],[[5888,5900],\\\"valid\\\"],[[5901,5901],\\\"disallowed\\\"],[[5902,5908],\\\"valid\\\"],[[5909,5919],\\\"disallowed\\\"],[[5920,5940],\\\"valid\\\"],[[5941,5942],\\\"valid\\\",[],\\\"NV8\\\"],[[5943,5951],\\\"disallowed\\\"],[[5952,5971],\\\"valid\\\"],[[5972,5983],\\\"disallowed\\\"],[[5984,5996],\\\"valid\\\"],[[5997,5997],\\\"disallowed\\\"],[[5998,6000],\\\"valid\\\"],[[6001,6001],\\\"disallowed\\\"],[[6002,6003],\\\"valid\\\"],[[6004,6015],\\\"disallowed\\\"],[[6016,6067],\\\"valid\\\"],[[6068,6069],\\\"disallowed\\\"],[[6070,6099],\\\"valid\\\"],[[6100,6102],\\\"valid\\\",[],\\\"NV8\\\"],[[6103,6103],\\\"valid\\\"],[[6104,6107],\\\"valid\\\",[],\\\"NV8\\\"],[[6108,6108],\\\"valid\\\"],[[6109,6109],\\\"valid\\\"],[[6110,6111],\\\"disallowed\\\"],[[6112,6121],\\\"valid\\\"],[[6122,6127],\\\"disallowed\\\"],[[6128,6137],\\\"valid\\\",[],\\\"NV8\\\"],[[6138,6143],\\\"disallowed\\\"],[[6144,6149],\\\"valid\\\",[],\\\"NV8\\\"],[[6150,6150],\\\"disallowed\\\"],[[6151,6154],\\\"valid\\\",[],\\\"NV8\\\"],[[6155,6157],\\\"ignored\\\"],[[6158,6158],\\\"disallowed\\\"],[[6159,6159],\\\"disallowed\\\"],[[6160,6169],\\\"valid\\\"],[[6170,6175],\\\"disallowed\\\"],[[6176,6263],\\\"valid\\\"],[[6264,6271],\\\"disallowed\\\"],[[6272,6313],\\\"valid\\\"],[[6314,6314],\\\"valid\\\"],[[6315,6319],\\\"disallowed\\\"],[[6320,6389],\\\"valid\\\"],[[6390,6399],\\\"disallowed\\\"],[[6400,6428],\\\"valid\\\"],[[6429,6430],\\\"valid\\\"],[[6431,6431],\\\"disallowed\\\"],[[6432,6443],\\\"valid\\\"],[[6444,6447],\\\"disallowed\\\"],[[6448,6459],\\\"valid\\\"],[[6460,6463],\\\"disallowed\\\"],[[6464,6464],\\\"valid\\\",[],\\\"NV8\\\"],[[6465,6467],\\\"disallowed\\\"],[[6468,6469],\\\"valid\\\",[],\\\"NV8\\\"],[[6470,6509],\\\"valid\\\"],[[6510,6511],\\\"disallowed\\\"],[[6512,6516],\\\"valid\\\"],[[6517,6527],\\\"disallowed\\\"],[[6528,6569],\\\"valid\\\"],[[6570,6571],\\\"valid\\\"],[[6572,6575],\\\"disallowed\\\"],[[6576,6601],\\\"valid\\\"],[[6602,6607],\\\"disallowed\\\"],[[6608,6617],\\\"valid\\\"],[[6618,6618],\\\"valid\\\",[],\\\"XV8\\\"],[[6619,6621],\\\"disallowed\\\"],[[6622,6623],\\\"valid\\\",[],\\\"NV8\\\"],[[6624,6655],\\\"valid\\\",[],\\\"NV8\\\"],[[6656,6683],\\\"valid\\\"],[[6684,6685],\\\"disallowed\\\"],[[6686,6687],\\\"valid\\\",[],\\\"NV8\\\"],[[6688,6750],\\\"valid\\\"],[[6751,6751],\\\"disallowed\\\"],[[6752,6780],\\\"valid\\\"],[[6781,6782],\\\"disallowed\\\"],[[6783,6793],\\\"valid\\\"],[[6794,6799],\\\"disallowed\\\"],[[6800,6809],\\\"valid\\\"],[[6810,6815],\\\"disallowed\\\"],[[6816,6822],\\\"valid\\\",[],\\\"NV8\\\"],[[6823,6823],\\\"valid\\\"],[[6824,6829],\\\"valid\\\",[],\\\"NV8\\\"],[[6830,6831],\\\"disallowed\\\"],[[6832,6845],\\\"valid\\\"],[[6846,6846],\\\"valid\\\",[],\\\"NV8\\\"],[[6847,6911],\\\"disallowed\\\"],[[6912,6987],\\\"valid\\\"],[[6988,6991],\\\"disallowed\\\"],[[6992,7001],\\\"valid\\\"],[[7002,7018],\\\"valid\\\",[],\\\"NV8\\\"],[[7019,7027],\\\"valid\\\"],[[7028,7036],\\\"valid\\\",[],\\\"NV8\\\"],[[7037,7039],\\\"disallowed\\\"],[[7040,7082],\\\"valid\\\"],[[7083,7085],\\\"valid\\\"],[[7086,7097],\\\"valid\\\"],[[7098,7103],\\\"valid\\\"],[[7104,7155],\\\"valid\\\"],[[7156,7163],\\\"disallowed\\\"],[[7164,7167],\\\"valid\\\",[],\\\"NV8\\\"],[[7168,7223],\\\"valid\\\"],[[7224,7226],\\\"disallowed\\\"],[[7227,7231],\\\"valid\\\",[],\\\"NV8\\\"],[[7232,7241],\\\"valid\\\"],[[7242,7244],\\\"disallowed\\\"],[[7245,7293],\\\"valid\\\"],[[7294,7295],\\\"valid\\\",[],\\\"NV8\\\"],[[7296,7359],\\\"disallowed\\\"],[[7360,7367],\\\"valid\\\",[],\\\"NV8\\\"],[[7368,7375],\\\"disallowed\\\"],[[7376,7378],\\\"valid\\\"],[[7379,7379],\\\"valid\\\",[],\\\"NV8\\\"],[[7380,7410],\\\"valid\\\"],[[7411,7414],\\\"valid\\\"],[[7415,7415],\\\"disallowed\\\"],[[7416,7417],\\\"valid\\\"],[[7418,7423],\\\"disallowed\\\"],[[7424,7467],\\\"valid\\\"],[[7468,7468],\\\"mapped\\\",[97]],[[7469,7469],\\\"mapped\\\",[230]],[[7470,7470],\\\"mapped\\\",[98]],[[7471,7471],\\\"valid\\\"],[[7472,7472],\\\"mapped\\\",[100]],[[7473,7473],\\\"mapped\\\",[101]],[[7474,7474],\\\"mapped\\\",[477]],[[7475,7475],\\\"mapped\\\",[103]],[[7476,7476],\\\"mapped\\\",[104]],[[7477,7477],\\\"mapped\\\",[105]],[[7478,7478],\\\"mapped\\\",[106]],[[7479,7479],\\\"mapped\\\",[107]],[[7480,7480],\\\"mapped\\\",[108]],[[7481,7481],\\\"mapped\\\",[109]],[[7482,7482],\\\"mapped\\\",[110]],[[7483,7483],\\\"valid\\\"],[[7484,7484],\\\"mapped\\\",[111]],[[7485,7485],\\\"mapped\\\",[547]],[[7486,7486],\\\"mapped\\\",[112]],[[7487,7487],\\\"mapped\\\",[114]],[[7488,7488],\\\"mapped\\\",[116]],[[7489,7489],\\\"mapped\\\",[117]],[[7490,7490],\\\"mapped\\\",[119]],[[7491,7491],\\\"mapped\\\",[97]],[[7492,7492],\\\"mapped\\\",[592]],[[7493,7493],\\\"mapped\\\",[593]],[[7494,7494],\\\"mapped\\\",[7426]],[[7495,7495],\\\"mapped\\\",[98]],[[7496,7496],\\\"mapped\\\",[100]],[[7497,7497],\\\"mapped\\\",[101]],[[7498,7498],\\\"mapped\\\",[601]],[[7499,7499],\\\"mapped\\\",[603]],[[7500,7500],\\\"mapped\\\",[604]],[[7501,7501],\\\"mapped\\\",[103]],[[7502,7502],\\\"valid\\\"],[[7503,7503],\\\"mapped\\\",[107]],[[7504,7504],\\\"mapped\\\",[109]],[[7505,7505],\\\"mapped\\\",[331]],[[7506,7506],\\\"mapped\\\",[111]],[[7507,7507],\\\"mapped\\\",[596]],[[7508,7508],\\\"mapped\\\",[7446]],[[7509,7509],\\\"mapped\\\",[7447]],[[7510,7510],\\\"mapped\\\",[112]],[[7511,7511],\\\"mapped\\\",[116]],[[7512,7512],\\\"mapped\\\",[117]],[[7513,7513],\\\"mapped\\\",[7453]],[[7514,7514],\\\"mapped\\\",[623]],[[7515,7515],\\\"mapped\\\",[118]],[[7516,7516],\\\"mapped\\\",[7461]],[[7517,7517],\\\"mapped\\\",[946]],[[7518,7518],\\\"mapped\\\",[947]],[[7519,7519],\\\"mapped\\\",[948]],[[7520,7520],\\\"mapped\\\",[966]],[[7521,7521],\\\"mapped\\\",[967]],[[7522,7522],\\\"mapped\\\",[105]],[[7523,7523],\\\"mapped\\\",[114]],[[7524,7524],\\\"mapped\\\",[117]],[[7525,7525],\\\"mapped\\\",[118]],[[7526,7526],\\\"mapped\\\",[946]],[[7527,7527],\\\"mapped\\\",[947]],[[7528,7528],\\\"mapped\\\",[961]],[[7529,7529],\\\"mapped\\\",[966]],[[7530,7530],\\\"mapped\\\",[967]],[[7531,7531],\\\"valid\\\"],[[7532,7543],\\\"valid\\\"],[[7544,7544],\\\"mapped\\\",[1085]],[[7545,7578],\\\"valid\\\"],[[7579,7579],\\\"mapped\\\",[594]],[[7580,7580],\\\"mapped\\\",[99]],[[7581,7581],\\\"mapped\\\",[597]],[[7582,7582],\\\"mapped\\\",[240]],[[7583,7583],\\\"mapped\\\",[604]],[[7584,7584],\\\"mapped\\\",[102]],[[7585,7585],\\\"mapped\\\",[607]],[[7586,7586],\\\"mapped\\\",[609]],[[7587,7587],\\\"mapped\\\",[613]],[[7588,7588],\\\"mapped\\\",[616]],[[7589,7589],\\\"mapped\\\",[617]],[[7590,7590],\\\"mapped\\\",[618]],[[7591,7591],\\\"mapped\\\",[7547]],[[7592,7592],\\\"mapped\\\",[669]],[[7593,7593],\\\"mapped\\\",[621]],[[7594,7594],\\\"mapped\\\",[7557]],[[7595,7595],\\\"mapped\\\",[671]],[[7596,7596],\\\"mapped\\\",[625]],[[7597,7597],\\\"mapped\\\",[624]],[[7598,7598],\\\"mapped\\\",[626]],[[7599,7599],\\\"mapped\\\",[627]],[[7600,7600],\\\"mapped\\\",[628]],[[7601,7601],\\\"mapped\\\",[629]],[[7602,7602],\\\"mapped\\\",[632]],[[7603,7603],\\\"mapped\\\",[642]],[[7604,7604],\\\"mapped\\\",[643]],[[7605,7605],\\\"mapped\\\",[427]],[[7606,7606],\\\"mapped\\\",[649]],[[7607,7607],\\\"mapped\\\",[650]],[[7608,7608],\\\"mapped\\\",[7452]],[[7609,7609],\\\"mapped\\\",[651]],[[7610,7610],\\\"mapped\\\",[652]],[[7611,7611],\\\"mapped\\\",[122]],[[7612,7612],\\\"mapped\\\",[656]],[[7613,7613],\\\"mapped\\\",[657]],[[7614,7614],\\\"mapped\\\",[658]],[[7615,7615],\\\"mapped\\\",[952]],[[7616,7619],\\\"valid\\\"],[[7620,7626],\\\"valid\\\"],[[7627,7654],\\\"valid\\\"],[[7655,7669],\\\"valid\\\"],[[7670,7675],\\\"disallowed\\\"],[[7676,7676],\\\"valid\\\"],[[7677,7677],\\\"valid\\\"],[[7678,7679],\\\"valid\\\"],[[7680,7680],\\\"mapped\\\",[7681]],[[7681,7681],\\\"valid\\\"],[[7682,7682],\\\"mapped\\\",[7683]],[[7683,7683],\\\"valid\\\"],[[7684,7684],\\\"mapped\\\",[7685]],[[7685,7685],\\\"valid\\\"],[[7686,7686],\\\"mapped\\\",[7687]],[[7687,7687],\\\"valid\\\"],[[7688,7688],\\\"mapped\\\",[7689]],[[7689,7689],\\\"valid\\\"],[[7690,7690],\\\"mapped\\\",[7691]],[[7691,7691],\\\"valid\\\"],[[7692,7692],\\\"mapped\\\",[7693]],[[7693,7693],\\\"valid\\\"],[[7694,7694],\\\"mapped\\\",[7695]],[[7695,7695],\\\"valid\\\"],[[7696,7696],\\\"mapped\\\",[7697]],[[7697,7697],\\\"valid\\\"],[[7698,7698],\\\"mapped\\\",[7699]],[[7699,7699],\\\"valid\\\"],[[7700,7700],\\\"mapped\\\",[7701]],[[7701,7701],\\\"valid\\\"],[[7702,7702],\\\"mapped\\\",[7703]],[[7703,7703],\\\"valid\\\"],[[7704,7704],\\\"mapped\\\",[7705]],[[7705,7705],\\\"valid\\\"],[[7706,7706],\\\"mapped\\\",[7707]],[[7707,7707],\\\"valid\\\"],[[7708,7708],\\\"mapped\\\",[7709]],[[7709,7709],\\\"valid\\\"],[[7710,7710],\\\"mapped\\\",[7711]],[[7711,7711],\\\"valid\\\"],[[7712,7712],\\\"mapped\\\",[7713]],[[7713,7713],\\\"valid\\\"],[[7714,7714],\\\"mapped\\\",[7715]],[[7715,7715],\\\"valid\\\"],[[7716,7716],\\\"mapped\\\",[7717]],[[7717,7717],\\\"valid\\\"],[[7718,7718],\\\"mapped\\\",[7719]],[[7719,7719],\\\"valid\\\"],[[7720,7720],\\\"mapped\\\",[7721]],[[7721,7721],\\\"valid\\\"],[[7722,7722],\\\"mapped\\\",[7723]],[[7723,7723],\\\"valid\\\"],[[7724,7724],\\\"mapped\\\",[7725]],[[7725,7725],\\\"valid\\\"],[[7726,7726],\\\"mapped\\\",[7727]],[[7727,7727],\\\"valid\\\"],[[7728,7728],\\\"mapped\\\",[7729]],[[7729,7729],\\\"valid\\\"],[[7730,7730],\\\"mapped\\\",[7731]],[[7731,7731],\\\"valid\\\"],[[7732,7732],\\\"mapped\\\",[7733]],[[7733,7733],\\\"valid\\\"],[[7734,7734],\\\"mapped\\\",[7735]],[[7735,7735],\\\"valid\\\"],[[7736,7736],\\\"mapped\\\",[7737]],[[7737,7737],\\\"valid\\\"],[[7738,7738],\\\"mapped\\\",[7739]],[[7739,7739],\\\"valid\\\"],[[7740,7740],\\\"mapped\\\",[7741]],[[7741,7741],\\\"valid\\\"],[[7742,7742],\\\"mapped\\\",[7743]],[[7743,7743],\\\"valid\\\"],[[7744,7744],\\\"mapped\\\",[7745]],[[7745,7745],\\\"valid\\\"],[[7746,7746],\\\"mapped\\\",[7747]],[[7747,7747],\\\"valid\\\"],[[7748,7748],\\\"mapped\\\",[7749]],[[7749,7749],\\\"valid\\\"],[[7750,7750],\\\"mapped\\\",[7751]],[[7751,7751],\\\"valid\\\"],[[7752,7752],\\\"mapped\\\",[7753]],[[7753,7753],\\\"valid\\\"],[[7754,7754],\\\"mapped\\\",[7755]],[[7755,7755],\\\"valid\\\"],[[7756,7756],\\\"mapped\\\",[7757]],[[7757,7757],\\\"valid\\\"],[[7758,7758],\\\"mapped\\\",[7759]],[[7759,7759],\\\"valid\\\"],[[7760,7760],\\\"mapped\\\",[7761]],[[7761,7761],\\\"valid\\\"],[[7762,7762],\\\"mapped\\\",[7763]],[[7763,7763],\\\"valid\\\"],[[7764,7764],\\\"mapped\\\",[7765]],[[7765,7765],\\\"valid\\\"],[[7766,7766],\\\"mapped\\\",[7767]],[[7767,7767],\\\"valid\\\"],[[7768,7768],\\\"mapped\\\",[7769]],[[7769,7769],\\\"valid\\\"],[[7770,7770],\\\"mapped\\\",[7771]],[[7771,7771],\\\"valid\\\"],[[7772,7772],\\\"mapped\\\",[7773]],[[7773,7773],\\\"valid\\\"],[[7774,7774],\\\"mapped\\\",[7775]],[[7775,7775],\\\"valid\\\"],[[7776,7776],\\\"mapped\\\",[7777]],[[7777,7777],\\\"valid\\\"],[[7778,7778],\\\"mapped\\\",[7779]],[[7779,7779],\\\"valid\\\"],[[7780,7780],\\\"mapped\\\",[7781]],[[7781,7781],\\\"valid\\\"],[[7782,7782],\\\"mapped\\\",[7783]],[[7783,7783],\\\"valid\\\"],[[7784,7784],\\\"mapped\\\",[7785]],[[7785,7785],\\\"valid\\\"],[[7786,7786],\\\"mapped\\\",[7787]],[[7787,7787],\\\"valid\\\"],[[7788,7788],\\\"mapped\\\",[7789]],[[7789,7789],\\\"valid\\\"],[[7790,7790],\\\"mapped\\\",[7791]],[[7791,7791],\\\"valid\\\"],[[7792,7792],\\\"mapped\\\",[7793]],[[7793,7793],\\\"valid\\\"],[[7794,7794],\\\"mapped\\\",[7795]],[[7795,7795],\\\"valid\\\"],[[7796,7796],\\\"mapped\\\",[7797]],[[7797,7797],\\\"valid\\\"],[[7798,7798],\\\"mapped\\\",[7799]],[[7799,7799],\\\"valid\\\"],[[7800,7800],\\\"mapped\\\",[7801]],[[7801,7801],\\\"valid\\\"],[[7802,7802],\\\"mapped\\\",[7803]],[[7803,7803],\\\"valid\\\"],[[7804,7804],\\\"mapped\\\",[7805]],[[7805,7805],\\\"valid\\\"],[[7806,7806],\\\"mapped\\\",[7807]],[[7807,7807],\\\"valid\\\"],[[7808,7808],\\\"mapped\\\",[7809]],[[7809,7809],\\\"valid\\\"],[[7810,7810],\\\"mapped\\\",[7811]],[[7811,7811],\\\"valid\\\"],[[7812,7812],\\\"mapped\\\",[7813]],[[7813,7813],\\\"valid\\\"],[[7814,7814],\\\"mapped\\\",[7815]],[[7815,7815],\\\"valid\\\"],[[7816,7816],\\\"mapped\\\",[7817]],[[7817,7817],\\\"valid\\\"],[[7818,7818],\\\"mapped\\\",[7819]],[[7819,7819],\\\"valid\\\"],[[7820,7820],\\\"mapped\\\",[7821]],[[7821,7821],\\\"valid\\\"],[[7822,7822],\\\"mapped\\\",[7823]],[[7823,7823],\\\"valid\\\"],[[7824,7824],\\\"mapped\\\",[7825]],[[7825,7825],\\\"valid\\\"],[[7826,7826],\\\"mapped\\\",[7827]],[[7827,7827],\\\"valid\\\"],[[7828,7828],\\\"mapped\\\",[7829]],[[7829,7833],\\\"valid\\\"],[[7834,7834],\\\"mapped\\\",[97,702]],[[7835,7835],\\\"mapped\\\",[7777]],[[7836,7837],\\\"valid\\\"],[[7838,7838],\\\"mapped\\\",[115,115]],[[7839,7839],\\\"valid\\\"],[[7840,7840],\\\"mapped\\\",[7841]],[[7841,7841],\\\"valid\\\"],[[7842,7842],\\\"mapped\\\",[7843]],[[7843,7843],\\\"valid\\\"],[[7844,7844],\\\"mapped\\\",[7845]],[[7845,7845],\\\"valid\\\"],[[7846,7846],\\\"mapped\\\",[7847]],[[7847,7847],\\\"valid\\\"],[[7848,7848],\\\"mapped\\\",[7849]],[[7849,7849],\\\"valid\\\"],[[7850,7850],\\\"mapped\\\",[7851]],[[7851,7851],\\\"valid\\\"],[[7852,7852],\\\"mapped\\\",[7853]],[[7853,7853],\\\"valid\\\"],[[7854,7854],\\\"mapped\\\",[7855]],[[7855,7855],\\\"valid\\\"],[[7856,7856],\\\"mapped\\\",[7857]],[[7857,7857],\\\"valid\\\"],[[7858,7858],\\\"mapped\\\",[7859]],[[7859,7859],\\\"valid\\\"],[[7860,7860],\\\"mapped\\\",[7861]],[[7861,7861],\\\"valid\\\"],[[7862,7862],\\\"mapped\\\",[7863]],[[7863,7863],\\\"valid\\\"],[[7864,7864],\\\"mapped\\\",[7865]],[[7865,7865],\\\"valid\\\"],[[7866,7866],\\\"mapped\\\",[7867]],[[7867,7867],\\\"valid\\\"],[[7868,7868],\\\"mapped\\\",[7869]],[[7869,7869],\\\"valid\\\"],[[7870,7870],\\\"mapped\\\",[7871]],[[7871,7871],\\\"valid\\\"],[[7872,7872],\\\"mapped\\\",[7873]],[[7873,7873],\\\"valid\\\"],[[7874,7874],\\\"mapped\\\",[7875]],[[7875,7875],\\\"valid\\\"],[[7876,7876],\\\"mapped\\\",[7877]],[[7877,7877],\\\"valid\\\"],[[7878,7878],\\\"mapped\\\",[7879]],[[7879,7879],\\\"valid\\\"],[[7880,7880],\\\"mapped\\\",[7881]],[[7881,7881],\\\"valid\\\"],[[7882,7882],\\\"mapped\\\",[7883]],[[7883,7883],\\\"valid\\\"],[[7884,7884],\\\"mapped\\\",[7885]],[[7885,7885],\\\"valid\\\"],[[7886,7886],\\\"mapped\\\",[7887]],[[7887,7887],\\\"valid\\\"],[[7888,7888],\\\"mapped\\\",[7889]],[[7889,7889],\\\"valid\\\"],[[7890,7890],\\\"mapped\\\",[7891]],[[7891,7891],\\\"valid\\\"],[[7892,7892],\\\"mapped\\\",[7893]],[[7893,7893],\\\"valid\\\"],[[7894,7894],\\\"mapped\\\",[7895]],[[7895,7895],\\\"valid\\\"],[[7896,7896],\\\"mapped\\\",[7897]],[[7897,7897],\\\"valid\\\"],[[7898,7898],\\\"mapped\\\",[7899]],[[7899,7899],\\\"valid\\\"],[[7900,7900],\\\"mapped\\\",[7901]],[[7901,7901],\\\"valid\\\"],[[7902,7902],\\\"mapped\\\",[7903]],[[7903,7903],\\\"valid\\\"],[[7904,7904],\\\"mapped\\\",[7905]],[[7905,7905],\\\"valid\\\"],[[7906,7906],\\\"mapped\\\",[7907]],[[7907,7907],\\\"valid\\\"],[[7908,7908],\\\"mapped\\\",[7909]],[[7909,7909],\\\"valid\\\"],[[7910,7910],\\\"mapped\\\",[7911]],[[7911,7911],\\\"valid\\\"],[[7912,7912],\\\"mapped\\\",[7913]],[[7913,7913],\\\"valid\\\"],[[7914,7914],\\\"mapped\\\",[7915]],[[7915,7915],\\\"valid\\\"],[[7916,7916],\\\"mapped\\\",[7917]],[[7917,7917],\\\"valid\\\"],[[7918,7918],\\\"mapped\\\",[7919]],[[7919,7919],\\\"valid\\\"],[[7920,7920],\\\"mapped\\\",[7921]],[[7921,7921],\\\"valid\\\"],[[7922,7922],\\\"mapped\\\",[7923]],[[7923,7923],\\\"valid\\\"],[[7924,7924],\\\"mapped\\\",[7925]],[[7925,7925],\\\"valid\\\"],[[7926,7926],\\\"mapped\\\",[7927]],[[7927,7927],\\\"valid\\\"],[[7928,7928],\\\"mapped\\\",[7929]],[[7929,7929],\\\"valid\\\"],[[7930,7930],\\\"mapped\\\",[7931]],[[7931,7931],\\\"valid\\\"],[[7932,7932],\\\"mapped\\\",[7933]],[[7933,7933],\\\"valid\\\"],[[7934,7934],\\\"mapped\\\",[7935]],[[7935,7935],\\\"valid\\\"],[[7936,7943],\\\"valid\\\"],[[7944,7944],\\\"mapped\\\",[7936]],[[7945,7945],\\\"mapped\\\",[7937]],[[7946,7946],\\\"mapped\\\",[7938]],[[7947,7947],\\\"mapped\\\",[7939]],[[7948,7948],\\\"mapped\\\",[7940]],[[7949,7949],\\\"mapped\\\",[7941]],[[7950,7950],\\\"mapped\\\",[7942]],[[7951,7951],\\\"mapped\\\",[7943]],[[7952,7957],\\\"valid\\\"],[[7958,7959],\\\"disallowed\\\"],[[7960,7960],\\\"mapped\\\",[7952]],[[7961,7961],\\\"mapped\\\",[7953]],[[7962,7962],\\\"mapped\\\",[7954]],[[7963,7963],\\\"mapped\\\",[7955]],[[7964,7964],\\\"mapped\\\",[7956]],[[7965,7965],\\\"mapped\\\",[7957]],[[7966,7967],\\\"disallowed\\\"],[[7968,7975],\\\"valid\\\"],[[7976,7976],\\\"mapped\\\",[7968]],[[7977,7977],\\\"mapped\\\",[7969]],[[7978,7978],\\\"mapped\\\",[7970]],[[7979,7979],\\\"mapped\\\",[7971]],[[7980,7980],\\\"mapped\\\",[7972]],[[7981,7981],\\\"mapped\\\",[7973]],[[7982,7982],\\\"mapped\\\",[7974]],[[7983,7983],\\\"mapped\\\",[7975]],[[7984,7991],\\\"valid\\\"],[[7992,7992],\\\"mapped\\\",[7984]],[[7993,7993],\\\"mapped\\\",[7985]],[[7994,7994],\\\"mapped\\\",[7986]],[[7995,7995],\\\"mapped\\\",[7987]],[[7996,7996],\\\"mapped\\\",[7988]],[[7997,7997],\\\"mapped\\\",[7989]],[[7998,7998],\\\"mapped\\\",[7990]],[[7999,7999],\\\"mapped\\\",[7991]],[[8000,8005],\\\"valid\\\"],[[8006,8007],\\\"disallowed\\\"],[[8008,8008],\\\"mapped\\\",[8000]],[[8009,8009],\\\"mapped\\\",[8001]],[[8010,8010],\\\"mapped\\\",[8002]],[[8011,8011],\\\"mapped\\\",[8003]],[[8012,8012],\\\"mapped\\\",[8004]],[[8013,8013],\\\"mapped\\\",[8005]],[[8014,8015],\\\"disallowed\\\"],[[8016,8023],\\\"valid\\\"],[[8024,8024],\\\"disallowed\\\"],[[8025,8025],\\\"mapped\\\",[8017]],[[8026,8026],\\\"disallowed\\\"],[[8027,8027],\\\"mapped\\\",[8019]],[[8028,8028],\\\"disallowed\\\"],[[8029,8029],\\\"mapped\\\",[8021]],[[8030,8030],\\\"disallowed\\\"],[[8031,8031],\\\"mapped\\\",[8023]],[[8032,8039],\\\"valid\\\"],[[8040,8040],\\\"mapped\\\",[8032]],[[8041,8041],\\\"mapped\\\",[8033]],[[8042,8042],\\\"mapped\\\",[8034]],[[8043,8043],\\\"mapped\\\",[8035]],[[8044,8044],\\\"mapped\\\",[8036]],[[8045,8045],\\\"mapped\\\",[8037]],[[8046,8046],\\\"mapped\\\",[8038]],[[8047,8047],\\\"mapped\\\",[8039]],[[8048,8048],\\\"valid\\\"],[[8049,8049],\\\"mapped\\\",[940]],[[8050,8050],\\\"valid\\\"],[[8051,8051],\\\"mapped\\\",[941]],[[8052,8052],\\\"valid\\\"],[[8053,8053],\\\"mapped\\\",[942]],[[8054,8054],\\\"valid\\\"],[[8055,8055],\\\"mapped\\\",[943]],[[8056,8056],\\\"valid\\\"],[[8057,8057],\\\"mapped\\\",[972]],[[8058,8058],\\\"valid\\\"],[[8059,8059],\\\"mapped\\\",[973]],[[8060,8060],\\\"valid\\\"],[[8061,8061],\\\"mapped\\\",[974]],[[8062,8063],\\\"disallowed\\\"],[[8064,8064],\\\"mapped\\\",[7936,953]],[[8065,8065],\\\"mapped\\\",[7937,953]],[[8066,8066],\\\"mapped\\\",[7938,953]],[[8067,8067],\\\"mapped\\\",[7939,953]],[[8068,8068],\\\"mapped\\\",[7940,953]],[[8069,8069],\\\"mapped\\\",[7941,953]],[[8070,8070],\\\"mapped\\\",[7942,953]],[[8071,8071],\\\"mapped\\\",[7943,953]],[[8072,8072],\\\"mapped\\\",[7936,953]],[[8073,8073],\\\"mapped\\\",[7937,953]],[[8074,8074],\\\"mapped\\\",[7938,953]],[[8075,8075],\\\"mapped\\\",[7939,953]],[[8076,8076],\\\"mapped\\\",[7940,953]],[[8077,8077],\\\"mapped\\\",[7941,953]],[[8078,8078],\\\"mapped\\\",[7942,953]],[[8079,8079],\\\"mapped\\\",[7943,953]],[[8080,8080],\\\"mapped\\\",[7968,953]],[[8081,8081],\\\"mapped\\\",[7969,953]],[[8082,8082],\\\"mapped\\\",[7970,953]],[[8083,8083],\\\"mapped\\\",[7971,953]],[[8084,8084],\\\"mapped\\\",[7972,953]],[[8085,8085],\\\"mapped\\\",[7973,953]],[[8086,8086],\\\"mapped\\\",[7974,953]],[[8087,8087],\\\"mapped\\\",[7975,953]],[[8088,8088],\\\"mapped\\\",[7968,953]],[[8089,8089],\\\"mapped\\\",[7969,953]],[[8090,8090],\\\"mapped\\\",[7970,953]],[[8091,8091],\\\"mapped\\\",[7971,953]],[[8092,8092],\\\"mapped\\\",[7972,953]],[[8093,8093],\\\"mapped\\\",[7973,953]],[[8094,8094],\\\"mapped\\\",[7974,953]],[[8095,8095],\\\"mapped\\\",[7975,953]],[[8096,8096],\\\"mapped\\\",[8032,953]],[[8097,8097],\\\"mapped\\\",[8033,953]],[[8098,8098],\\\"mapped\\\",[8034,953]],[[8099,8099],\\\"mapped\\\",[8035,953]],[[8100,8100],\\\"mapped\\\",[8036,953]],[[8101,8101],\\\"mapped\\\",[8037,953]],[[8102,8102],\\\"mapped\\\",[8038,953]],[[8103,8103],\\\"mapped\\\",[8039,953]],[[8104,8104],\\\"mapped\\\",[8032,953]],[[8105,8105],\\\"mapped\\\",[8033,953]],[[8106,8106],\\\"mapped\\\",[8034,953]],[[8107,8107],\\\"mapped\\\",[8035,953]],[[8108,8108],\\\"mapped\\\",[8036,953]],[[8109,8109],\\\"mapped\\\",[8037,953]],[[8110,8110],\\\"mapped\\\",[8038,953]],[[8111,8111],\\\"mapped\\\",[8039,953]],[[8112,8113],\\\"valid\\\"],[[8114,8114],\\\"mapped\\\",[8048,953]],[[8115,8115],\\\"mapped\\\",[945,953]],[[8116,8116],\\\"mapped\\\",[940,953]],[[8117,8117],\\\"disallowed\\\"],[[8118,8118],\\\"valid\\\"],[[8119,8119],\\\"mapped\\\",[8118,953]],[[8120,8120],\\\"mapped\\\",[8112]],[[8121,8121],\\\"mapped\\\",[8113]],[[8122,8122],\\\"mapped\\\",[8048]],[[8123,8123],\\\"mapped\\\",[940]],[[8124,8124],\\\"mapped\\\",[945,953]],[[8125,8125],\\\"disallowed_STD3_mapped\\\",[32,787]],[[8126,8126],\\\"mapped\\\",[953]],[[8127,8127],\\\"disallowed_STD3_mapped\\\",[32,787]],[[8128,8128],\\\"disallowed_STD3_mapped\\\",[32,834]],[[8129,8129],\\\"disallowed_STD3_mapped\\\",[32,776,834]],[[8130,8130],\\\"mapped\\\",[8052,953]],[[8131,8131],\\\"mapped\\\",[951,953]],[[8132,8132],\\\"mapped\\\",[942,953]],[[8133,8133],\\\"disallowed\\\"],[[8134,8134],\\\"valid\\\"],[[8135,8135],\\\"mapped\\\",[8134,953]],[[8136,8136],\\\"mapped\\\",[8050]],[[8137,8137],\\\"mapped\\\",[941]],[[8138,8138],\\\"mapped\\\",[8052]],[[8139,8139],\\\"mapped\\\",[942]],[[8140,8140],\\\"mapped\\\",[951,953]],[[8141,8141],\\\"disallowed_STD3_mapped\\\",[32,787,768]],[[8142,8142],\\\"disallowed_STD3_mapped\\\",[32,787,769]],[[8143,8143],\\\"disallowed_STD3_mapped\\\",[32,787,834]],[[8144,8146],\\\"valid\\\"],[[8147,8147],\\\"mapped\\\",[912]],[[8148,8149],\\\"disallowed\\\"],[[8150,8151],\\\"valid\\\"],[[8152,8152],\\\"mapped\\\",[8144]],[[8153,8153],\\\"mapped\\\",[8145]],[[8154,8154],\\\"mapped\\\",[8054]],[[8155,8155],\\\"mapped\\\",[943]],[[8156,8156],\\\"disallowed\\\"],[[8157,8157],\\\"disallowed_STD3_mapped\\\",[32,788,768]],[[8158,8158],\\\"disallowed_STD3_mapped\\\",[32,788,769]],[[8159,8159],\\\"disallowed_STD3_mapped\\\",[32,788,834]],[[8160,8162],\\\"valid\\\"],[[8163,8163],\\\"mapped\\\",[944]],[[8164,8167],\\\"valid\\\"],[[8168,8168],\\\"mapped\\\",[8160]],[[8169,8169],\\\"mapped\\\",[8161]],[[8170,8170],\\\"mapped\\\",[8058]],[[8171,8171],\\\"mapped\\\",[973]],[[8172,8172],\\\"mapped\\\",[8165]],[[8173,8173],\\\"disallowed_STD3_mapped\\\",[32,776,768]],[[8174,8174],\\\"disallowed_STD3_mapped\\\",[32,776,769]],[[8175,8175],\\\"disallowed_STD3_mapped\\\",[96]],[[8176,8177],\\\"disallowed\\\"],[[8178,8178],\\\"mapped\\\",[8060,953]],[[8179,8179],\\\"mapped\\\",[969,953]],[[8180,8180],\\\"mapped\\\",[974,953]],[[8181,8181],\\\"disallowed\\\"],[[8182,8182],\\\"valid\\\"],[[8183,8183],\\\"mapped\\\",[8182,953]],[[8184,8184],\\\"mapped\\\",[8056]],[[8185,8185],\\\"mapped\\\",[972]],[[8186,8186],\\\"mapped\\\",[8060]],[[8187,8187],\\\"mapped\\\",[974]],[[8188,8188],\\\"mapped\\\",[969,953]],[[8189,8189],\\\"disallowed_STD3_mapped\\\",[32,769]],[[8190,8190],\\\"disallowed_STD3_mapped\\\",[32,788]],[[8191,8191],\\\"disallowed\\\"],[[8192,8202],\\\"disallowed_STD3_mapped\\\",[32]],[[8203,8203],\\\"ignored\\\"],[[8204,8205],\\\"deviation\\\",[]],[[8206,8207],\\\"disallowed\\\"],[[8208,8208],\\\"valid\\\",[],\\\"NV8\\\"],[[8209,8209],\\\"mapped\\\",[8208]],[[8210,8214],\\\"valid\\\",[],\\\"NV8\\\"],[[8215,8215],\\\"disallowed_STD3_mapped\\\",[32,819]],[[8216,8227],\\\"valid\\\",[],\\\"NV8\\\"],[[8228,8230],\\\"disallowed\\\"],[[8231,8231],\\\"valid\\\",[],\\\"NV8\\\"],[[8232,8238],\\\"disallowed\\\"],[[8239,8239],\\\"disallowed_STD3_mapped\\\",[32]],[[8240,8242],\\\"valid\\\",[],\\\"NV8\\\"],[[8243,8243],\\\"mapped\\\",[8242,8242]],[[8244,8244],\\\"mapped\\\",[8242,8242,8242]],[[8245,8245],\\\"valid\\\",[],\\\"NV8\\\"],[[8246,8246],\\\"mapped\\\",[8245,8245]],[[8247,8247],\\\"mapped\\\",[8245,8245,8245]],[[8248,8251],\\\"valid\\\",[],\\\"NV8\\\"],[[8252,8252],\\\"disallowed_STD3_mapped\\\",[33,33]],[[8253,8253],\\\"valid\\\",[],\\\"NV8\\\"],[[8254,8254],\\\"disallowed_STD3_mapped\\\",[32,773]],[[8255,8262],\\\"valid\\\",[],\\\"NV8\\\"],[[8263,8263],\\\"disallowed_STD3_mapped\\\",[63,63]],[[8264,8264],\\\"disallowed_STD3_mapped\\\",[63,33]],[[8265,8265],\\\"disallowed_STD3_mapped\\\",[33,63]],[[8266,8269],\\\"valid\\\",[],\\\"NV8\\\"],[[8270,8274],\\\"valid\\\",[],\\\"NV8\\\"],[[8275,8276],\\\"valid\\\",[],\\\"NV8\\\"],[[8277,8278],\\\"valid\\\",[],\\\"NV8\\\"],[[8279,8279],\\\"mapped\\\",[8242,8242,8242,8242]],[[8280,8286],\\\"valid\\\",[],\\\"NV8\\\"],[[8287,8287],\\\"disallowed_STD3_mapped\\\",[32]],[[8288,8288],\\\"ignored\\\"],[[8289,8291],\\\"disallowed\\\"],[[8292,8292],\\\"ignored\\\"],[[8293,8293],\\\"disallowed\\\"],[[8294,8297],\\\"disallowed\\\"],[[8298,8303],\\\"disallowed\\\"],[[8304,8304],\\\"mapped\\\",[48]],[[8305,8305],\\\"mapped\\\",[105]],[[8306,8307],\\\"disallowed\\\"],[[8308,8308],\\\"mapped\\\",[52]],[[8309,8309],\\\"mapped\\\",[53]],[[8310,8310],\\\"mapped\\\",[54]],[[8311,8311],\\\"mapped\\\",[55]],[[8312,8312],\\\"mapped\\\",[56]],[[8313,8313],\\\"mapped\\\",[57]],[[8314,8314],\\\"disallowed_STD3_mapped\\\",[43]],[[8315,8315],\\\"mapped\\\",[8722]],[[8316,8316],\\\"disallowed_STD3_mapped\\\",[61]],[[8317,8317],\\\"disallowed_STD3_mapped\\\",[40]],[[8318,8318],\\\"disallowed_STD3_mapped\\\",[41]],[[8319,8319],\\\"mapped\\\",[110]],[[8320,8320],\\\"mapped\\\",[48]],[[8321,8321],\\\"mapped\\\",[49]],[[8322,8322],\\\"mapped\\\",[50]],[[8323,8323],\\\"mapped\\\",[51]],[[8324,8324],\\\"mapped\\\",[52]],[[8325,8325],\\\"mapped\\\",[53]],[[8326,8326],\\\"mapped\\\",[54]],[[8327,8327],\\\"mapped\\\",[55]],[[8328,8328],\\\"mapped\\\",[56]],[[8329,8329],\\\"mapped\\\",[57]],[[8330,8330],\\\"disallowed_STD3_mapped\\\",[43]],[[8331,8331],\\\"mapped\\\",[8722]],[[8332,8332],\\\"disallowed_STD3_mapped\\\",[61]],[[8333,8333],\\\"disallowed_STD3_mapped\\\",[40]],[[8334,8334],\\\"disallowed_STD3_mapped\\\",[41]],[[8335,8335],\\\"disallowed\\\"],[[8336,8336],\\\"mapped\\\",[97]],[[8337,8337],\\\"mapped\\\",[101]],[[8338,8338],\\\"mapped\\\",[111]],[[8339,8339],\\\"mapped\\\",[120]],[[8340,8340],\\\"mapped\\\",[601]],[[8341,8341],\\\"mapped\\\",[104]],[[8342,8342],\\\"mapped\\\",[107]],[[8343,8343],\\\"mapped\\\",[108]],[[8344,8344],\\\"mapped\\\",[109]],[[8345,8345],\\\"mapped\\\",[110]],[[8346,8346],\\\"mapped\\\",[112]],[[8347,8347],\\\"mapped\\\",[115]],[[8348,8348],\\\"mapped\\\",[116]],[[8349,8351],\\\"disallowed\\\"],[[8352,8359],\\\"valid\\\",[],\\\"NV8\\\"],[[8360,8360],\\\"mapped\\\",[114,115]],[[8361,8362],\\\"valid\\\",[],\\\"NV8\\\"],[[8363,8363],\\\"valid\\\",[],\\\"NV8\\\"],[[8364,8364],\\\"valid\\\",[],\\\"NV8\\\"],[[8365,8367],\\\"valid\\\",[],\\\"NV8\\\"],[[8368,8369],\\\"valid\\\",[],\\\"NV8\\\"],[[8370,8373],\\\"valid\\\",[],\\\"NV8\\\"],[[8374,8376],\\\"valid\\\",[],\\\"NV8\\\"],[[8377,8377],\\\"valid\\\",[],\\\"NV8\\\"],[[8378,8378],\\\"valid\\\",[],\\\"NV8\\\"],[[8379,8381],\\\"valid\\\",[],\\\"NV8\\\"],[[8382,8382],\\\"valid\\\",[],\\\"NV8\\\"],[[8383,8399],\\\"disallowed\\\"],[[8400,8417],\\\"valid\\\",[],\\\"NV8\\\"],[[8418,8419],\\\"valid\\\",[],\\\"NV8\\\"],[[8420,8426],\\\"valid\\\",[],\\\"NV8\\\"],[[8427,8427],\\\"valid\\\",[],\\\"NV8\\\"],[[8428,8431],\\\"valid\\\",[],\\\"NV8\\\"],[[8432,8432],\\\"valid\\\",[],\\\"NV8\\\"],[[8433,8447],\\\"disallowed\\\"],[[8448,8448],\\\"disallowed_STD3_mapped\\\",[97,47,99]],[[8449,8449],\\\"disallowed_STD3_mapped\\\",[97,47,115]],[[8450,8450],\\\"mapped\\\",[99]],[[8451,8451],\\\"mapped\\\",[176,99]],[[8452,8452],\\\"valid\\\",[],\\\"NV8\\\"],[[8453,8453],\\\"disallowed_STD3_mapped\\\",[99,47,111]],[[8454,8454],\\\"disallowed_STD3_mapped\\\",[99,47,117]],[[8455,8455],\\\"mapped\\\",[603]],[[8456,8456],\\\"valid\\\",[],\\\"NV8\\\"],[[8457,8457],\\\"mapped\\\",[176,102]],[[8458,8458],\\\"mapped\\\",[103]],[[8459,8462],\\\"mapped\\\",[104]],[[8463,8463],\\\"mapped\\\",[295]],[[8464,8465],\\\"mapped\\\",[105]],[[8466,8467],\\\"mapped\\\",[108]],[[8468,8468],\\\"valid\\\",[],\\\"NV8\\\"],[[8469,8469],\\\"mapped\\\",[110]],[[8470,8470],\\\"mapped\\\",[110,111]],[[8471,8472],\\\"valid\\\",[],\\\"NV8\\\"],[[8473,8473],\\\"mapped\\\",[112]],[[8474,8474],\\\"mapped\\\",[113]],[[8475,8477],\\\"mapped\\\",[114]],[[8478,8479],\\\"valid\\\",[],\\\"NV8\\\"],[[8480,8480],\\\"mapped\\\",[115,109]],[[8481,8481],\\\"mapped\\\",[116,101,108]],[[8482,8482],\\\"mapped\\\",[116,109]],[[8483,8483],\\\"valid\\\",[],\\\"NV8\\\"],[[8484,8484],\\\"mapped\\\",[122]],[[8485,8485],\\\"valid\\\",[],\\\"NV8\\\"],[[8486,8486],\\\"mapped\\\",[969]],[[8487,8487],\\\"valid\\\",[],\\\"NV8\\\"],[[8488,8488],\\\"mapped\\\",[122]],[[8489,8489],\\\"valid\\\",[],\\\"NV8\\\"],[[8490,8490],\\\"mapped\\\",[107]],[[8491,8491],\\\"mapped\\\",[229]],[[8492,8492],\\\"mapped\\\",[98]],[[8493,8493],\\\"mapped\\\",[99]],[[8494,8494],\\\"valid\\\",[],\\\"NV8\\\"],[[8495,8496],\\\"mapped\\\",[101]],[[8497,8497],\\\"mapped\\\",[102]],[[8498,8498],\\\"disallowed\\\"],[[8499,8499],\\\"mapped\\\",[109]],[[8500,8500],\\\"mapped\\\",[111]],[[8501,8501],\\\"mapped\\\",[1488]],[[8502,8502],\\\"mapped\\\",[1489]],[[8503,8503],\\\"mapped\\\",[1490]],[[8504,8504],\\\"mapped\\\",[1491]],[[8505,8505],\\\"mapped\\\",[105]],[[8506,8506],\\\"valid\\\",[],\\\"NV8\\\"],[[8507,8507],\\\"mapped\\\",[102,97,120]],[[8508,8508],\\\"mapped\\\",[960]],[[8509,8510],\\\"mapped\\\",[947]],[[8511,8511],\\\"mapped\\\",[960]],[[8512,8512],\\\"mapped\\\",[8721]],[[8513,8516],\\\"valid\\\",[],\\\"NV8\\\"],[[8517,8518],\\\"mapped\\\",[100]],[[8519,8519],\\\"mapped\\\",[101]],[[8520,8520],\\\"mapped\\\",[105]],[[8521,8521],\\\"mapped\\\",[106]],[[8522,8523],\\\"valid\\\",[],\\\"NV8\\\"],[[8524,8524],\\\"valid\\\",[],\\\"NV8\\\"],[[8525,8525],\\\"valid\\\",[],\\\"NV8\\\"],[[8526,8526],\\\"valid\\\"],[[8527,8527],\\\"valid\\\",[],\\\"NV8\\\"],[[8528,8528],\\\"mapped\\\",[49,8260,55]],[[8529,8529],\\\"mapped\\\",[49,8260,57]],[[8530,8530],\\\"mapped\\\",[49,8260,49,48]],[[8531,8531],\\\"mapped\\\",[49,8260,51]],[[8532,8532],\\\"mapped\\\",[50,8260,51]],[[8533,8533],\\\"mapped\\\",[49,8260,53]],[[8534,8534],\\\"mapped\\\",[50,8260,53]],[[8535,8535],\\\"mapped\\\",[51,8260,53]],[[8536,8536],\\\"mapped\\\",[52,8260,53]],[[8537,8537],\\\"mapped\\\",[49,8260,54]],[[8538,8538],\\\"mapped\\\",[53,8260,54]],[[8539,8539],\\\"mapped\\\",[49,8260,56]],[[8540,8540],\\\"mapped\\\",[51,8260,56]],[[8541,8541],\\\"mapped\\\",[53,8260,56]],[[8542,8542],\\\"mapped\\\",[55,8260,56]],[[8543,8543],\\\"mapped\\\",[49,8260]],[[8544,8544],\\\"mapped\\\",[105]],[[8545,8545],\\\"mapped\\\",[105,105]],[[8546,8546],\\\"mapped\\\",[105,105,105]],[[8547,8547],\\\"mapped\\\",[105,118]],[[8548,8548],\\\"mapped\\\",[118]],[[8549,8549],\\\"mapped\\\",[118,105]],[[8550,8550],\\\"mapped\\\",[118,105,105]],[[8551,8551],\\\"mapped\\\",[118,105,105,105]],[[8552,8552],\\\"mapped\\\",[105,120]],[[8553,8553],\\\"mapped\\\",[120]],[[8554,8554],\\\"mapped\\\",[120,105]],[[8555,8555],\\\"mapped\\\",[120,105,105]],[[8556,8556],\\\"mapped\\\",[108]],[[8557,8557],\\\"mapped\\\",[99]],[[8558,8558],\\\"mapped\\\",[100]],[[8559,8559],\\\"mapped\\\",[109]],[[8560,8560],\\\"mapped\\\",[105]],[[8561,8561],\\\"mapped\\\",[105,105]],[[8562,8562],\\\"mapped\\\",[105,105,105]],[[8563,8563],\\\"mapped\\\",[105,118]],[[8564,8564],\\\"mapped\\\",[118]],[[8565,8565],\\\"mapped\\\",[118,105]],[[8566,8566],\\\"mapped\\\",[118,105,105]],[[8567,8567],\\\"mapped\\\",[118,105,105,105]],[[8568,8568],\\\"mapped\\\",[105,120]],[[8569,8569],\\\"mapped\\\",[120]],[[8570,8570],\\\"mapped\\\",[120,105]],[[8571,8571],\\\"mapped\\\",[120,105,105]],[[8572,8572],\\\"mapped\\\",[108]],[[8573,8573],\\\"mapped\\\",[99]],[[8574,8574],\\\"mapped\\\",[100]],[[8575,8575],\\\"mapped\\\",[109]],[[8576,8578],\\\"valid\\\",[],\\\"NV8\\\"],[[8579,8579],\\\"disallowed\\\"],[[8580,8580],\\\"valid\\\"],[[8581,8584],\\\"valid\\\",[],\\\"NV8\\\"],[[8585,8585],\\\"mapped\\\",[48,8260,51]],[[8586,8587],\\\"valid\\\",[],\\\"NV8\\\"],[[8588,8591],\\\"disallowed\\\"],[[8592,8682],\\\"valid\\\",[],\\\"NV8\\\"],[[8683,8691],\\\"valid\\\",[],\\\"NV8\\\"],[[8692,8703],\\\"valid\\\",[],\\\"NV8\\\"],[[8704,8747],\\\"valid\\\",[],\\\"NV8\\\"],[[8748,8748],\\\"mapped\\\",[8747,8747]],[[8749,8749],\\\"mapped\\\",[8747,8747,8747]],[[8750,8750],\\\"valid\\\",[],\\\"NV8\\\"],[[8751,8751],\\\"mapped\\\",[8750,8750]],[[8752,8752],\\\"mapped\\\",[8750,8750,8750]],[[8753,8799],\\\"valid\\\",[],\\\"NV8\\\"],[[8800,8800],\\\"disallowed_STD3_valid\\\"],[[8801,8813],\\\"valid\\\",[],\\\"NV8\\\"],[[8814,8815],\\\"disallowed_STD3_valid\\\"],[[8816,8945],\\\"valid\\\",[],\\\"NV8\\\"],[[8946,8959],\\\"valid\\\",[],\\\"NV8\\\"],[[8960,8960],\\\"valid\\\",[],\\\"NV8\\\"],[[8961,8961],\\\"valid\\\",[],\\\"NV8\\\"],[[8962,9000],\\\"valid\\\",[],\\\"NV8\\\"],[[9001,9001],\\\"mapped\\\",[12296]],[[9002,9002],\\\"mapped\\\",[12297]],[[9003,9082],\\\"valid\\\",[],\\\"NV8\\\"],[[9083,9083],\\\"valid\\\",[],\\\"NV8\\\"],[[9084,9084],\\\"valid\\\",[],\\\"NV8\\\"],[[9085,9114],\\\"valid\\\",[],\\\"NV8\\\"],[[9115,9166],\\\"valid\\\",[],\\\"NV8\\\"],[[9167,9168],\\\"valid\\\",[],\\\"NV8\\\"],[[9169,9179],\\\"valid\\\",[],\\\"NV8\\\"],[[9180,9191],\\\"valid\\\",[],\\\"NV8\\\"],[[9192,9192],\\\"valid\\\",[],\\\"NV8\\\"],[[9193,9203],\\\"valid\\\",[],\\\"NV8\\\"],[[9204,9210],\\\"valid\\\",[],\\\"NV8\\\"],[[9211,9215],\\\"disallowed\\\"],[[9216,9252],\\\"valid\\\",[],\\\"NV8\\\"],[[9253,9254],\\\"valid\\\",[],\\\"NV8\\\"],[[9255,9279],\\\"disallowed\\\"],[[9280,9290],\\\"valid\\\",[],\\\"NV8\\\"],[[9291,9311],\\\"disallowed\\\"],[[9312,9312],\\\"mapped\\\",[49]],[[9313,9313],\\\"mapped\\\",[50]],[[9314,9314],\\\"mapped\\\",[51]],[[9315,9315],\\\"mapped\\\",[52]],[[9316,9316],\\\"mapped\\\",[53]],[[9317,9317],\\\"mapped\\\",[54]],[[9318,9318],\\\"mapped\\\",[55]],[[9319,9319],\\\"mapped\\\",[56]],[[9320,9320],\\\"mapped\\\",[57]],[[9321,9321],\\\"mapped\\\",[49,48]],[[9322,9322],\\\"mapped\\\",[49,49]],[[9323,9323],\\\"mapped\\\",[49,50]],[[9324,9324],\\\"mapped\\\",[49,51]],[[9325,9325],\\\"mapped\\\",[49,52]],[[9326,9326],\\\"mapped\\\",[49,53]],[[9327,9327],\\\"mapped\\\",[49,54]],[[9328,9328],\\\"mapped\\\",[49,55]],[[9329,9329],\\\"mapped\\\",[49,56]],[[9330,9330],\\\"mapped\\\",[49,57]],[[9331,9331],\\\"mapped\\\",[50,48]],[[9332,9332],\\\"disallowed_STD3_mapped\\\",[40,49,41]],[[9333,9333],\\\"disallowed_STD3_mapped\\\",[40,50,41]],[[9334,9334],\\\"disallowed_STD3_mapped\\\",[40,51,41]],[[9335,9335],\\\"disallowed_STD3_mapped\\\",[40,52,41]],[[9336,9336],\\\"disallowed_STD3_mapped\\\",[40,53,41]],[[9337,9337],\\\"disallowed_STD3_mapped\\\",[40,54,41]],[[9338,9338],\\\"disallowed_STD3_mapped\\\",[40,55,41]],[[9339,9339],\\\"disallowed_STD3_mapped\\\",[40,56,41]],[[9340,9340],\\\"disallowed_STD3_mapped\\\",[40,57,41]],[[9341,9341],\\\"disallowed_STD3_mapped\\\",[40,49,48,41]],[[9342,9342],\\\"disallowed_STD3_mapped\\\",[40,49,49,41]],[[9343,9343],\\\"disallowed_STD3_mapped\\\",[40,49,50,41]],[[9344,9344],\\\"disallowed_STD3_mapped\\\",[40,49,51,41]],[[9345,9345],\\\"disallowed_STD3_mapped\\\",[40,49,52,41]],[[9346,9346],\\\"disallowed_STD3_mapped\\\",[40,49,53,41]],[[9347,9347],\\\"disallowed_STD3_mapped\\\",[40,49,54,41]],[[9348,9348],\\\"disallowed_STD3_mapped\\\",[40,49,55,41]],[[9349,9349],\\\"disallowed_STD3_mapped\\\",[40,49,56,41]],[[9350,9350],\\\"disallowed_STD3_mapped\\\",[40,49,57,41]],[[9351,9351],\\\"disallowed_STD3_mapped\\\",[40,50,48,41]],[[9352,9371],\\\"disallowed\\\"],[[9372,9372],\\\"disallowed_STD3_mapped\\\",[40,97,41]],[[9373,9373],\\\"disallowed_STD3_mapped\\\",[40,98,41]],[[9374,9374],\\\"disallowed_STD3_mapped\\\",[40,99,41]],[[9375,9375],\\\"disallowed_STD3_mapped\\\",[40,100,41]],[[9376,9376],\\\"disallowed_STD3_mapped\\\",[40,101,41]],[[9377,9377],\\\"disallowed_STD3_mapped\\\",[40,102,41]],[[9378,9378],\\\"disallowed_STD3_mapped\\\",[40,103,41]],[[9379,9379],\\\"disallowed_STD3_mapped\\\",[40,104,41]],[[9380,9380],\\\"disallowed_STD3_mapped\\\",[40,105,41]],[[9381,9381],\\\"disallowed_STD3_mapped\\\",[40,106,41]],[[9382,9382],\\\"disallowed_STD3_mapped\\\",[40,107,41]],[[9383,9383],\\\"disallowed_STD3_mapped\\\",[40,108,41]],[[9384,9384],\\\"disallowed_STD3_mapped\\\",[40,109,41]],[[9385,9385],\\\"disallowed_STD3_mapped\\\",[40,110,41]],[[9386,9386],\\\"disallowed_STD3_mapped\\\",[40,111,41]],[[9387,9387],\\\"disallowed_STD3_mapped\\\",[40,112,41]],[[9388,9388],\\\"disallowed_STD3_mapped\\\",[40,113,41]],[[9389,9389],\\\"disallowed_STD3_mapped\\\",[40,114,41]],[[9390,9390],\\\"disallowed_STD3_mapped\\\",[40,115,41]],[[9391,9391],\\\"disallowed_STD3_mapped\\\",[40,116,41]],[[9392,9392],\\\"disallowed_STD3_mapped\\\",[40,117,41]],[[9393,9393],\\\"disallowed_STD3_mapped\\\",[40,118,41]],[[9394,9394],\\\"disallowed_STD3_mapped\\\",[40,119,41]],[[9395,9395],\\\"disallowed_STD3_mapped\\\",[40,120,41]],[[9396,9396],\\\"disallowed_STD3_mapped\\\",[40,121,41]],[[9397,9397],\\\"disallowed_STD3_mapped\\\",[40,122,41]],[[9398,9398],\\\"mapped\\\",[97]],[[9399,9399],\\\"mapped\\\",[98]],[[9400,9400],\\\"mapped\\\",[99]],[[9401,9401],\\\"mapped\\\",[100]],[[9402,9402],\\\"mapped\\\",[101]],[[9403,9403],\\\"mapped\\\",[102]],[[9404,9404],\\\"mapped\\\",[103]],[[9405,9405],\\\"mapped\\\",[104]],[[9406,9406],\\\"mapped\\\",[105]],[[9407,9407],\\\"mapped\\\",[106]],[[9408,9408],\\\"mapped\\\",[107]],[[9409,9409],\\\"mapped\\\",[108]],[[9410,9410],\\\"mapped\\\",[109]],[[9411,9411],\\\"mapped\\\",[110]],[[9412,9412],\\\"mapped\\\",[111]],[[9413,9413],\\\"mapped\\\",[112]],[[9414,9414],\\\"mapped\\\",[113]],[[9415,9415],\\\"mapped\\\",[114]],[[9416,9416],\\\"mapped\\\",[115]],[[9417,9417],\\\"mapped\\\",[116]],[[9418,9418],\\\"mapped\\\",[117]],[[9419,9419],\\\"mapped\\\",[118]],[[9420,9420],\\\"mapped\\\",[119]],[[9421,9421],\\\"mapped\\\",[120]],[[9422,9422],\\\"mapped\\\",[121]],[[9423,9423],\\\"mapped\\\",[122]],[[9424,9424],\\\"mapped\\\",[97]],[[9425,9425],\\\"mapped\\\",[98]],[[9426,9426],\\\"mapped\\\",[99]],[[9427,9427],\\\"mapped\\\",[100]],[[9428,9428],\\\"mapped\\\",[101]],[[9429,9429],\\\"mapped\\\",[102]],[[9430,9430],\\\"mapped\\\",[103]],[[9431,9431],\\\"mapped\\\",[104]],[[9432,9432],\\\"mapped\\\",[105]],[[9433,9433],\\\"mapped\\\",[106]],[[9434,9434],\\\"mapped\\\",[107]],[[9435,9435],\\\"mapped\\\",[108]],[[9436,9436],\\\"mapped\\\",[109]],[[9437,9437],\\\"mapped\\\",[110]],[[9438,9438],\\\"mapped\\\",[111]],[[9439,9439],\\\"mapped\\\",[112]],[[9440,9440],\\\"mapped\\\",[113]],[[9441,9441],\\\"mapped\\\",[114]],[[9442,9442],\\\"mapped\\\",[115]],[[9443,9443],\\\"mapped\\\",[116]],[[9444,9444],\\\"mapped\\\",[117]],[[9445,9445],\\\"mapped\\\",[118]],[[9446,9446],\\\"mapped\\\",[119]],[[9447,9447],\\\"mapped\\\",[120]],[[9448,9448],\\\"mapped\\\",[121]],[[9449,9449],\\\"mapped\\\",[122]],[[9450,9450],\\\"mapped\\\",[48]],[[9451,9470],\\\"valid\\\",[],\\\"NV8\\\"],[[9471,9471],\\\"valid\\\",[],\\\"NV8\\\"],[[9472,9621],\\\"valid\\\",[],\\\"NV8\\\"],[[9622,9631],\\\"valid\\\",[],\\\"NV8\\\"],[[9632,9711],\\\"valid\\\",[],\\\"NV8\\\"],[[9712,9719],\\\"valid\\\",[],\\\"NV8\\\"],[[9720,9727],\\\"valid\\\",[],\\\"NV8\\\"],[[9728,9747],\\\"valid\\\",[],\\\"NV8\\\"],[[9748,9749],\\\"valid\\\",[],\\\"NV8\\\"],[[9750,9751],\\\"valid\\\",[],\\\"NV8\\\"],[[9752,9752],\\\"valid\\\",[],\\\"NV8\\\"],[[9753,9753],\\\"valid\\\",[],\\\"NV8\\\"],[[9754,9839],\\\"valid\\\",[],\\\"NV8\\\"],[[9840,9841],\\\"valid\\\",[],\\\"NV8\\\"],[[9842,9853],\\\"valid\\\",[],\\\"NV8\\\"],[[9854,9855],\\\"valid\\\",[],\\\"NV8\\\"],[[9856,9865],\\\"valid\\\",[],\\\"NV8\\\"],[[9866,9873],\\\"valid\\\",[],\\\"NV8\\\"],[[9874,9884],\\\"valid\\\",[],\\\"NV8\\\"],[[9885,9885],\\\"valid\\\",[],\\\"NV8\\\"],[[9886,9887],\\\"valid\\\",[],\\\"NV8\\\"],[[9888,9889],\\\"valid\\\",[],\\\"NV8\\\"],[[9890,9905],\\\"valid\\\",[],\\\"NV8\\\"],[[9906,9906],\\\"valid\\\",[],\\\"NV8\\\"],[[9907,9916],\\\"valid\\\",[],\\\"NV8\\\"],[[9917,9919],\\\"valid\\\",[],\\\"NV8\\\"],[[9920,9923],\\\"valid\\\",[],\\\"NV8\\\"],[[9924,9933],\\\"valid\\\",[],\\\"NV8\\\"],[[9934,9934],\\\"valid\\\",[],\\\"NV8\\\"],[[9935,9953],\\\"valid\\\",[],\\\"NV8\\\"],[[9954,9954],\\\"valid\\\",[],\\\"NV8\\\"],[[9955,9955],\\\"valid\\\",[],\\\"NV8\\\"],[[9956,9959],\\\"valid\\\",[],\\\"NV8\\\"],[[9960,9983],\\\"valid\\\",[],\\\"NV8\\\"],[[9984,9984],\\\"valid\\\",[],\\\"NV8\\\"],[[9985,9988],\\\"valid\\\",[],\\\"NV8\\\"],[[9989,9989],\\\"valid\\\",[],\\\"NV8\\\"],[[9990,9993],\\\"valid\\\",[],\\\"NV8\\\"],[[9994,9995],\\\"valid\\\",[],\\\"NV8\\\"],[[9996,10023],\\\"valid\\\",[],\\\"NV8\\\"],[[10024,10024],\\\"valid\\\",[],\\\"NV8\\\"],[[10025,10059],\\\"valid\\\",[],\\\"NV8\\\"],[[10060,10060],\\\"valid\\\",[],\\\"NV8\\\"],[[10061,10061],\\\"valid\\\",[],\\\"NV8\\\"],[[10062,10062],\\\"valid\\\",[],\\\"NV8\\\"],[[10063,10066],\\\"valid\\\",[],\\\"NV8\\\"],[[10067,10069],\\\"valid\\\",[],\\\"NV8\\\"],[[10070,10070],\\\"valid\\\",[],\\\"NV8\\\"],[[10071,10071],\\\"valid\\\",[],\\\"NV8\\\"],[[10072,10078],\\\"valid\\\",[],\\\"NV8\\\"],[[10079,10080],\\\"valid\\\",[],\\\"NV8\\\"],[[10081,10087],\\\"valid\\\",[],\\\"NV8\\\"],[[10088,10101],\\\"valid\\\",[],\\\"NV8\\\"],[[10102,10132],\\\"valid\\\",[],\\\"NV8\\\"],[[10133,10135],\\\"valid\\\",[],\\\"NV8\\\"],[[10136,10159],\\\"valid\\\",[],\\\"NV8\\\"],[[10160,10160],\\\"valid\\\",[],\\\"NV8\\\"],[[10161,10174],\\\"valid\\\",[],\\\"NV8\\\"],[[10175,10175],\\\"valid\\\",[],\\\"NV8\\\"],[[10176,10182],\\\"valid\\\",[],\\\"NV8\\\"],[[10183,10186],\\\"valid\\\",[],\\\"NV8\\\"],[[10187,10187],\\\"valid\\\",[],\\\"NV8\\\"],[[10188,10188],\\\"valid\\\",[],\\\"NV8\\\"],[[10189,10189],\\\"valid\\\",[],\\\"NV8\\\"],[[10190,10191],\\\"valid\\\",[],\\\"NV8\\\"],[[10192,10219],\\\"valid\\\",[],\\\"NV8\\\"],[[10220,10223],\\\"valid\\\",[],\\\"NV8\\\"],[[10224,10239],\\\"valid\\\",[],\\\"NV8\\\"],[[10240,10495],\\\"valid\\\",[],\\\"NV8\\\"],[[10496,10763],\\\"valid\\\",[],\\\"NV8\\\"],[[10764,10764],\\\"mapped\\\",[8747,8747,8747,8747]],[[10765,10867],\\\"valid\\\",[],\\\"NV8\\\"],[[10868,10868],\\\"disallowed_STD3_mapped\\\",[58,58,61]],[[10869,10869],\\\"disallowed_STD3_mapped\\\",[61,61]],[[10870,10870],\\\"disallowed_STD3_mapped\\\",[61,61,61]],[[10871,10971],\\\"valid\\\",[],\\\"NV8\\\"],[[10972,10972],\\\"mapped\\\",[10973,824]],[[10973,11007],\\\"valid\\\",[],\\\"NV8\\\"],[[11008,11021],\\\"valid\\\",[],\\\"NV8\\\"],[[11022,11027],\\\"valid\\\",[],\\\"NV8\\\"],[[11028,11034],\\\"valid\\\",[],\\\"NV8\\\"],[[11035,11039],\\\"valid\\\",[],\\\"NV8\\\"],[[11040,11043],\\\"valid\\\",[],\\\"NV8\\\"],[[11044,11084],\\\"valid\\\",[],\\\"NV8\\\"],[[11085,11087],\\\"valid\\\",[],\\\"NV8\\\"],[[11088,11092],\\\"valid\\\",[],\\\"NV8\\\"],[[11093,11097],\\\"valid\\\",[],\\\"NV8\\\"],[[11098,11123],\\\"valid\\\",[],\\\"NV8\\\"],[[11124,11125],\\\"disallowed\\\"],[[11126,11157],\\\"valid\\\",[],\\\"NV8\\\"],[[11158,11159],\\\"disallowed\\\"],[[11160,11193],\\\"valid\\\",[],\\\"NV8\\\"],[[11194,11196],\\\"disallowed\\\"],[[11197,11208],\\\"valid\\\",[],\\\"NV8\\\"],[[11209,11209],\\\"disallowed\\\"],[[11210,11217],\\\"valid\\\",[],\\\"NV8\\\"],[[11218,11243],\\\"disallowed\\\"],[[11244,11247],\\\"valid\\\",[],\\\"NV8\\\"],[[11248,11263],\\\"disallowed\\\"],[[11264,11264],\\\"mapped\\\",[11312]],[[11265,11265],\\\"mapped\\\",[11313]],[[11266,11266],\\\"mapped\\\",[11314]],[[11267,11267],\\\"mapped\\\",[11315]],[[11268,11268],\\\"mapped\\\",[11316]],[[11269,11269],\\\"mapped\\\",[11317]],[[11270,11270],\\\"mapped\\\",[11318]],[[11271,11271],\\\"mapped\\\",[11319]],[[11272,11272],\\\"mapped\\\",[11320]],[[11273,11273],\\\"mapped\\\",[11321]],[[11274,11274],\\\"mapped\\\",[11322]],[[11275,11275],\\\"mapped\\\",[11323]],[[11276,11276],\\\"mapped\\\",[11324]],[[11277,11277],\\\"mapped\\\",[11325]],[[11278,11278],\\\"mapped\\\",[11326]],[[11279,11279],\\\"mapped\\\",[11327]],[[11280,11280],\\\"mapped\\\",[11328]],[[11281,11281],\\\"mapped\\\",[11329]],[[11282,11282],\\\"mapped\\\",[11330]],[[11283,11283],\\\"mapped\\\",[11331]],[[11284,11284],\\\"mapped\\\",[11332]],[[11285,11285],\\\"mapped\\\",[11333]],[[11286,11286],\\\"mapped\\\",[11334]],[[11287,11287],\\\"mapped\\\",[11335]],[[11288,11288],\\\"mapped\\\",[11336]],[[11289,11289],\\\"mapped\\\",[11337]],[[11290,11290],\\\"mapped\\\",[11338]],[[11291,11291],\\\"mapped\\\",[11339]],[[11292,11292],\\\"mapped\\\",[11340]],[[11293,11293],\\\"mapped\\\",[11341]],[[11294,11294],\\\"mapped\\\",[11342]],[[11295,11295],\\\"mapped\\\",[11343]],[[11296,11296],\\\"mapped\\\",[11344]],[[11297,11297],\\\"mapped\\\",[11345]],[[11298,11298],\\\"mapped\\\",[11346]],[[11299,11299],\\\"mapped\\\",[11347]],[[11300,11300],\\\"mapped\\\",[11348]],[[11301,11301],\\\"mapped\\\",[11349]],[[11302,11302],\\\"mapped\\\",[11350]],[[11303,11303],\\\"mapped\\\",[11351]],[[11304,11304],\\\"mapped\\\",[11352]],[[11305,11305],\\\"mapped\\\",[11353]],[[11306,11306],\\\"mapped\\\",[11354]],[[11307,11307],\\\"mapped\\\",[11355]],[[11308,11308],\\\"mapped\\\",[11356]],[[11309,11309],\\\"mapped\\\",[11357]],[[11310,11310],\\\"mapped\\\",[11358]],[[11311,11311],\\\"disallowed\\\"],[[11312,11358],\\\"valid\\\"],[[11359,11359],\\\"disallowed\\\"],[[11360,11360],\\\"mapped\\\",[11361]],[[11361,11361],\\\"valid\\\"],[[11362,11362],\\\"mapped\\\",[619]],[[11363,11363],\\\"mapped\\\",[7549]],[[11364,11364],\\\"mapped\\\",[637]],[[11365,11366],\\\"valid\\\"],[[11367,11367],\\\"mapped\\\",[11368]],[[11368,11368],\\\"valid\\\"],[[11369,11369],\\\"mapped\\\",[11370]],[[11370,11370],\\\"valid\\\"],[[11371,11371],\\\"mapped\\\",[11372]],[[11372,11372],\\\"valid\\\"],[[11373,11373],\\\"mapped\\\",[593]],[[11374,11374],\\\"mapped\\\",[625]],[[11375,11375],\\\"mapped\\\",[592]],[[11376,11376],\\\"mapped\\\",[594]],[[11377,11377],\\\"valid\\\"],[[11378,11378],\\\"mapped\\\",[11379]],[[11379,11379],\\\"valid\\\"],[[11380,11380],\\\"valid\\\"],[[11381,11381],\\\"mapped\\\",[11382]],[[11382,11383],\\\"valid\\\"],[[11384,11387],\\\"valid\\\"],[[11388,11388],\\\"mapped\\\",[106]],[[11389,11389],\\\"mapped\\\",[118]],[[11390,11390],\\\"mapped\\\",[575]],[[11391,11391],\\\"mapped\\\",[576]],[[11392,11392],\\\"mapped\\\",[11393]],[[11393,11393],\\\"valid\\\"],[[11394,11394],\\\"mapped\\\",[11395]],[[11395,11395],\\\"valid\\\"],[[11396,11396],\\\"mapped\\\",[11397]],[[11397,11397],\\\"valid\\\"],[[11398,11398],\\\"mapped\\\",[11399]],[[11399,11399],\\\"valid\\\"],[[11400,11400],\\\"mapped\\\",[11401]],[[11401,11401],\\\"valid\\\"],[[11402,11402],\\\"mapped\\\",[11403]],[[11403,11403],\\\"valid\\\"],[[11404,11404],\\\"mapped\\\",[11405]],[[11405,11405],\\\"valid\\\"],[[11406,11406],\\\"mapped\\\",[11407]],[[11407,11407],\\\"valid\\\"],[[11408,11408],\\\"mapped\\\",[11409]],[[11409,11409],\\\"valid\\\"],[[11410,11410],\\\"mapped\\\",[11411]],[[11411,11411],\\\"valid\\\"],[[11412,11412],\\\"mapped\\\",[11413]],[[11413,11413],\\\"valid\\\"],[[11414,11414],\\\"mapped\\\",[11415]],[[11415,11415],\\\"valid\\\"],[[11416,11416],\\\"mapped\\\",[11417]],[[11417,11417],\\\"valid\\\"],[[11418,11418],\\\"mapped\\\",[11419]],[[11419,11419],\\\"valid\\\"],[[11420,11420],\\\"mapped\\\",[11421]],[[11421,11421],\\\"valid\\\"],[[11422,11422],\\\"mapped\\\",[11423]],[[11423,11423],\\\"valid\\\"],[[11424,11424],\\\"mapped\\\",[11425]],[[11425,11425],\\\"valid\\\"],[[11426,11426],\\\"mapped\\\",[11427]],[[11427,11427],\\\"valid\\\"],[[11428,11428],\\\"mapped\\\",[11429]],[[11429,11429],\\\"valid\\\"],[[11430,11430],\\\"mapped\\\",[11431]],[[11431,11431],\\\"valid\\\"],[[11432,11432],\\\"mapped\\\",[11433]],[[11433,11433],\\\"valid\\\"],[[11434,11434],\\\"mapped\\\",[11435]],[[11435,11435],\\\"valid\\\"],[[11436,11436],\\\"mapped\\\",[11437]],[[11437,11437],\\\"valid\\\"],[[11438,11438],\\\"mapped\\\",[11439]],[[11439,11439],\\\"valid\\\"],[[11440,11440],\\\"mapped\\\",[11441]],[[11441,11441],\\\"valid\\\"],[[11442,11442],\\\"mapped\\\",[11443]],[[11443,11443],\\\"valid\\\"],[[11444,11444],\\\"mapped\\\",[11445]],[[11445,11445],\\\"valid\\\"],[[11446,11446],\\\"mapped\\\",[11447]],[[11447,11447],\\\"valid\\\"],[[11448,11448],\\\"mapped\\\",[11449]],[[11449,11449],\\\"valid\\\"],[[11450,11450],\\\"mapped\\\",[11451]],[[11451,11451],\\\"valid\\\"],[[11452,11452],\\\"mapped\\\",[11453]],[[11453,11453],\\\"valid\\\"],[[11454,11454],\\\"mapped\\\",[11455]],[[11455,11455],\\\"valid\\\"],[[11456,11456],\\\"mapped\\\",[11457]],[[11457,11457],\\\"valid\\\"],[[11458,11458],\\\"mapped\\\",[11459]],[[11459,11459],\\\"valid\\\"],[[11460,11460],\\\"mapped\\\",[11461]],[[11461,11461],\\\"valid\\\"],[[11462,11462],\\\"mapped\\\",[11463]],[[11463,11463],\\\"valid\\\"],[[11464,11464],\\\"mapped\\\",[11465]],[[11465,11465],\\\"valid\\\"],[[11466,11466],\\\"mapped\\\",[11467]],[[11467,11467],\\\"valid\\\"],[[11468,11468],\\\"mapped\\\",[11469]],[[11469,11469],\\\"valid\\\"],[[11470,11470],\\\"mapped\\\",[11471]],[[11471,11471],\\\"valid\\\"],[[11472,11472],\\\"mapped\\\",[11473]],[[11473,11473],\\\"valid\\\"],[[11474,11474],\\\"mapped\\\",[11475]],[[11475,11475],\\\"valid\\\"],[[11476,11476],\\\"mapped\\\",[11477]],[[11477,11477],\\\"valid\\\"],[[11478,11478],\\\"mapped\\\",[11479]],[[11479,11479],\\\"valid\\\"],[[11480,11480],\\\"mapped\\\",[11481]],[[11481,11481],\\\"valid\\\"],[[11482,11482],\\\"mapped\\\",[11483]],[[11483,11483],\\\"valid\\\"],[[11484,11484],\\\"mapped\\\",[11485]],[[11485,11485],\\\"valid\\\"],[[11486,11486],\\\"mapped\\\",[11487]],[[11487,11487],\\\"valid\\\"],[[11488,11488],\\\"mapped\\\",[11489]],[[11489,11489],\\\"valid\\\"],[[11490,11490],\\\"mapped\\\",[11491]],[[11491,11492],\\\"valid\\\"],[[11493,11498],\\\"valid\\\",[],\\\"NV8\\\"],[[11499,11499],\\\"mapped\\\",[11500]],[[11500,11500],\\\"valid\\\"],[[11501,11501],\\\"mapped\\\",[11502]],[[11502,11505],\\\"valid\\\"],[[11506,11506],\\\"mapped\\\",[11507]],[[11507,11507],\\\"valid\\\"],[[11508,11512],\\\"disallowed\\\"],[[11513,11519],\\\"valid\\\",[],\\\"NV8\\\"],[[11520,11557],\\\"valid\\\"],[[11558,11558],\\\"disallowed\\\"],[[11559,11559],\\\"valid\\\"],[[11560,11564],\\\"disallowed\\\"],[[11565,11565],\\\"valid\\\"],[[11566,11567],\\\"disallowed\\\"],[[11568,11621],\\\"valid\\\"],[[11622,11623],\\\"valid\\\"],[[11624,11630],\\\"disallowed\\\"],[[11631,11631],\\\"mapped\\\",[11617]],[[11632,11632],\\\"valid\\\",[],\\\"NV8\\\"],[[11633,11646],\\\"disallowed\\\"],[[11647,11647],\\\"valid\\\"],[[11648,11670],\\\"valid\\\"],[[11671,11679],\\\"disallowed\\\"],[[11680,11686],\\\"valid\\\"],[[11687,11687],\\\"disallowed\\\"],[[11688,11694],\\\"valid\\\"],[[11695,11695],\\\"disallowed\\\"],[[11696,11702],\\\"valid\\\"],[[11703,11703],\\\"disallowed\\\"],[[11704,11710],\\\"valid\\\"],[[11711,11711],\\\"disallowed\\\"],[[11712,11718],\\\"valid\\\"],[[11719,11719],\\\"disallowed\\\"],[[11720,11726],\\\"valid\\\"],[[11727,11727],\\\"disallowed\\\"],[[11728,11734],\\\"valid\\\"],[[11735,11735],\\\"disallowed\\\"],[[11736,11742],\\\"valid\\\"],[[11743,11743],\\\"disallowed\\\"],[[11744,11775],\\\"valid\\\"],[[11776,11799],\\\"valid\\\",[],\\\"NV8\\\"],[[11800,11803],\\\"valid\\\",[],\\\"NV8\\\"],[[11804,11805],\\\"valid\\\",[],\\\"NV8\\\"],[[11806,11822],\\\"valid\\\",[],\\\"NV8\\\"],[[11823,11823],\\\"valid\\\"],[[11824,11824],\\\"valid\\\",[],\\\"NV8\\\"],[[11825,11825],\\\"valid\\\",[],\\\"NV8\\\"],[[11826,11835],\\\"valid\\\",[],\\\"NV8\\\"],[[11836,11842],\\\"valid\\\",[],\\\"NV8\\\"],[[11843,11903],\\\"disallowed\\\"],[[11904,11929],\\\"valid\\\",[],\\\"NV8\\\"],[[11930,11930],\\\"disallowed\\\"],[[11931,11934],\\\"valid\\\",[],\\\"NV8\\\"],[[11935,11935],\\\"mapped\\\",[27597]],[[11936,12018],\\\"valid\\\",[],\\\"NV8\\\"],[[12019,12019],\\\"mapped\\\",[40863]],[[12020,12031],\\\"disallowed\\\"],[[12032,12032],\\\"mapped\\\",[19968]],[[12033,12033],\\\"mapped\\\",[20008]],[[12034,12034],\\\"mapped\\\",[20022]],[[12035,12035],\\\"mapped\\\",[20031]],[[12036,12036],\\\"mapped\\\",[20057]],[[12037,12037],\\\"mapped\\\",[20101]],[[12038,12038],\\\"mapped\\\",[20108]],[[12039,12039],\\\"mapped\\\",[20128]],[[12040,12040],\\\"mapped\\\",[20154]],[[12041,12041],\\\"mapped\\\",[20799]],[[12042,12042],\\\"mapped\\\",[20837]],[[12043,12043],\\\"mapped\\\",[20843]],[[12044,12044],\\\"mapped\\\",[20866]],[[12045,12045],\\\"mapped\\\",[20886]],[[12046,12046],\\\"mapped\\\",[20907]],[[12047,12047],\\\"mapped\\\",[20960]],[[12048,12048],\\\"mapped\\\",[20981]],[[12049,12049],\\\"mapped\\\",[20992]],[[12050,12050],\\\"mapped\\\",[21147]],[[12051,12051],\\\"mapped\\\",[21241]],[[12052,12052],\\\"mapped\\\",[21269]],[[12053,12053],\\\"mapped\\\",[21274]],[[12054,12054],\\\"mapped\\\",[21304]],[[12055,12055],\\\"mapped\\\",[21313]],[[12056,12056],\\\"mapped\\\",[21340]],[[12057,12057],\\\"mapped\\\",[21353]],[[12058,12058],\\\"mapped\\\",[21378]],[[12059,12059],\\\"mapped\\\",[21430]],[[12060,12060],\\\"mapped\\\",[21448]],[[12061,12061],\\\"mapped\\\",[21475]],[[12062,12062],\\\"mapped\\\",[22231]],[[12063,12063],\\\"mapped\\\",[22303]],[[12064,12064],\\\"mapped\\\",[22763]],[[12065,12065],\\\"mapped\\\",[22786]],[[12066,12066],\\\"mapped\\\",[22794]],[[12067,12067],\\\"mapped\\\",[22805]],[[12068,12068],\\\"mapped\\\",[22823]],[[12069,12069],\\\"mapped\\\",[22899]],[[12070,12070],\\\"mapped\\\",[23376]],[[12071,12071],\\\"mapped\\\",[23424]],[[12072,12072],\\\"mapped\\\",[23544]],[[12073,12073],\\\"mapped\\\",[23567]],[[12074,12074],\\\"mapped\\\",[23586]],[[12075,12075],\\\"mapped\\\",[23608]],[[12076,12076],\\\"mapped\\\",[23662]],[[12077,12077],\\\"mapped\\\",[23665]],[[12078,12078],\\\"mapped\\\",[24027]],[[12079,12079],\\\"mapped\\\",[24037]],[[12080,12080],\\\"mapped\\\",[24049]],[[12081,12081],\\\"mapped\\\",[24062]],[[12082,12082],\\\"mapped\\\",[24178]],[[12083,12083],\\\"mapped\\\",[24186]],[[12084,12084],\\\"mapped\\\",[24191]],[[12085,12085],\\\"mapped\\\",[24308]],[[12086,12086],\\\"mapped\\\",[24318]],[[12087,12087],\\\"mapped\\\",[24331]],[[12088,12088],\\\"mapped\\\",[24339]],[[12089,12089],\\\"mapped\\\",[24400]],[[12090,12090],\\\"mapped\\\",[24417]],[[12091,12091],\\\"mapped\\\",[24435]],[[12092,12092],\\\"mapped\\\",[24515]],[[12093,12093],\\\"mapped\\\",[25096]],[[12094,12094],\\\"mapped\\\",[25142]],[[12095,12095],\\\"mapped\\\",[25163]],[[12096,12096],\\\"mapped\\\",[25903]],[[12097,12097],\\\"mapped\\\",[25908]],[[12098,12098],\\\"mapped\\\",[25991]],[[12099,12099],\\\"mapped\\\",[26007]],[[12100,12100],\\\"mapped\\\",[26020]],[[12101,12101],\\\"mapped\\\",[26041]],[[12102,12102],\\\"mapped\\\",[26080]],[[12103,12103],\\\"mapped\\\",[26085]],[[12104,12104],\\\"mapped\\\",[26352]],[[12105,12105],\\\"mapped\\\",[26376]],[[12106,12106],\\\"mapped\\\",[26408]],[[12107,12107],\\\"mapped\\\",[27424]],[[12108,12108],\\\"mapped\\\",[27490]],[[12109,12109],\\\"mapped\\\",[27513]],[[12110,12110],\\\"mapped\\\",[27571]],[[12111,12111],\\\"mapped\\\",[27595]],[[12112,12112],\\\"mapped\\\",[27604]],[[12113,12113],\\\"mapped\\\",[27611]],[[12114,12114],\\\"mapped\\\",[27663]],[[12115,12115],\\\"mapped\\\",[27668]],[[12116,12116],\\\"mapped\\\",[27700]],[[12117,12117],\\\"mapped\\\",[28779]],[[12118,12118],\\\"mapped\\\",[29226]],[[12119,12119],\\\"mapped\\\",[29238]],[[12120,12120],\\\"mapped\\\",[29243]],[[12121,12121],\\\"mapped\\\",[29247]],[[12122,12122],\\\"mapped\\\",[29255]],[[12123,12123],\\\"mapped\\\",[29273]],[[12124,12124],\\\"mapped\\\",[29275]],[[12125,12125],\\\"mapped\\\",[29356]],[[12126,12126],\\\"mapped\\\",[29572]],[[12127,12127],\\\"mapped\\\",[29577]],[[12128,12128],\\\"mapped\\\",[29916]],[[12129,12129],\\\"mapped\\\",[29926]],[[12130,12130],\\\"mapped\\\",[29976]],[[12131,12131],\\\"mapped\\\",[29983]],[[12132,12132],\\\"mapped\\\",[29992]],[[12133,12133],\\\"mapped\\\",[30000]],[[12134,12134],\\\"mapped\\\",[30091]],[[12135,12135],\\\"mapped\\\",[30098]],[[12136,12136],\\\"mapped\\\",[30326]],[[12137,12137],\\\"mapped\\\",[30333]],[[12138,12138],\\\"mapped\\\",[30382]],[[12139,12139],\\\"mapped\\\",[30399]],[[12140,12140],\\\"mapped\\\",[30446]],[[12141,12141],\\\"mapped\\\",[30683]],[[12142,12142],\\\"mapped\\\",[30690]],[[12143,12143],\\\"mapped\\\",[30707]],[[12144,12144],\\\"mapped\\\",[31034]],[[12145,12145],\\\"mapped\\\",[31160]],[[12146,12146],\\\"mapped\\\",[31166]],[[12147,12147],\\\"mapped\\\",[31348]],[[12148,12148],\\\"mapped\\\",[31435]],[[12149,12149],\\\"mapped\\\",[31481]],[[12150,12150],\\\"mapped\\\",[31859]],[[12151,12151],\\\"mapped\\\",[31992]],[[12152,12152],\\\"mapped\\\",[32566]],[[12153,12153],\\\"mapped\\\",[32593]],[[12154,12154],\\\"mapped\\\",[32650]],[[12155,12155],\\\"mapped\\\",[32701]],[[12156,12156],\\\"mapped\\\",[32769]],[[12157,12157],\\\"mapped\\\",[32780]],[[12158,12158],\\\"mapped\\\",[32786]],[[12159,12159],\\\"mapped\\\",[32819]],[[12160,12160],\\\"mapped\\\",[32895]],[[12161,12161],\\\"mapped\\\",[32905]],[[12162,12162],\\\"mapped\\\",[33251]],[[12163,12163],\\\"mapped\\\",[33258]],[[12164,12164],\\\"mapped\\\",[33267]],[[12165,12165],\\\"mapped\\\",[33276]],[[12166,12166],\\\"mapped\\\",[33292]],[[12167,12167],\\\"mapped\\\",[33307]],[[12168,12168],\\\"mapped\\\",[33311]],[[12169,12169],\\\"mapped\\\",[33390]],[[12170,12170],\\\"mapped\\\",[33394]],[[12171,12171],\\\"mapped\\\",[33400]],[[12172,12172],\\\"mapped\\\",[34381]],[[12173,12173],\\\"mapped\\\",[34411]],[[12174,12174],\\\"mapped\\\",[34880]],[[12175,12175],\\\"mapped\\\",[34892]],[[12176,12176],\\\"mapped\\\",[34915]],[[12177,12177],\\\"mapped\\\",[35198]],[[12178,12178],\\\"mapped\\\",[35211]],[[12179,12179],\\\"mapped\\\",[35282]],[[12180,12180],\\\"mapped\\\",[35328]],[[12181,12181],\\\"mapped\\\",[35895]],[[12182,12182],\\\"mapped\\\",[35910]],[[12183,12183],\\\"mapped\\\",[35925]],[[12184,12184],\\\"mapped\\\",[35960]],[[12185,12185],\\\"mapped\\\",[35997]],[[12186,12186],\\\"mapped\\\",[36196]],[[12187,12187],\\\"mapped\\\",[36208]],[[12188,12188],\\\"mapped\\\",[36275]],[[12189,12189],\\\"mapped\\\",[36523]],[[12190,12190],\\\"mapped\\\",[36554]],[[12191,12191],\\\"mapped\\\",[36763]],[[12192,12192],\\\"mapped\\\",[36784]],[[12193,12193],\\\"mapped\\\",[36789]],[[12194,12194],\\\"mapped\\\",[37009]],[[12195,12195],\\\"mapped\\\",[37193]],[[12196,12196],\\\"mapped\\\",[37318]],[[12197,12197],\\\"mapped\\\",[37324]],[[12198,12198],\\\"mapped\\\",[37329]],[[12199,12199],\\\"mapped\\\",[38263]],[[12200,12200],\\\"mapped\\\",[38272]],[[12201,12201],\\\"mapped\\\",[38428]],[[12202,12202],\\\"mapped\\\",[38582]],[[12203,12203],\\\"mapped\\\",[38585]],[[12204,12204],\\\"mapped\\\",[38632]],[[12205,12205],\\\"mapped\\\",[38737]],[[12206,12206],\\\"mapped\\\",[38750]],[[12207,12207],\\\"mapped\\\",[38754]],[[12208,12208],\\\"mapped\\\",[38761]],[[12209,12209],\\\"mapped\\\",[38859]],[[12210,12210],\\\"mapped\\\",[38893]],[[12211,12211],\\\"mapped\\\",[38899]],[[12212,12212],\\\"mapped\\\",[38913]],[[12213,12213],\\\"mapped\\\",[39080]],[[12214,12214],\\\"mapped\\\",[39131]],[[12215,12215],\\\"mapped\\\",[39135]],[[12216,12216],\\\"mapped\\\",[39318]],[[12217,12217],\\\"mapped\\\",[39321]],[[12218,12218],\\\"mapped\\\",[39340]],[[12219,12219],\\\"mapped\\\",[39592]],[[12220,12220],\\\"mapped\\\",[39640]],[[12221,12221],\\\"mapped\\\",[39647]],[[12222,12222],\\\"mapped\\\",[39717]],[[12223,12223],\\\"mapped\\\",[39727]],[[12224,12224],\\\"mapped\\\",[39730]],[[12225,12225],\\\"mapped\\\",[39740]],[[12226,12226],\\\"mapped\\\",[39770]],[[12227,12227],\\\"mapped\\\",[40165]],[[12228,12228],\\\"mapped\\\",[40565]],[[12229,12229],\\\"mapped\\\",[40575]],[[12230,12230],\\\"mapped\\\",[40613]],[[12231,12231],\\\"mapped\\\",[40635]],[[12232,12232],\\\"mapped\\\",[40643]],[[12233,12233],\\\"mapped\\\",[40653]],[[12234,12234],\\\"mapped\\\",[40657]],[[12235,12235],\\\"mapped\\\",[40697]],[[12236,12236],\\\"mapped\\\",[40701]],[[12237,12237],\\\"mapped\\\",[40718]],[[12238,12238],\\\"mapped\\\",[40723]],[[12239,12239],\\\"mapped\\\",[40736]],[[12240,12240],\\\"mapped\\\",[40763]],[[12241,12241],\\\"mapped\\\",[40778]],[[12242,12242],\\\"mapped\\\",[40786]],[[12243,12243],\\\"mapped\\\",[40845]],[[12244,12244],\\\"mapped\\\",[40860]],[[12245,12245],\\\"mapped\\\",[40864]],[[12246,12271],\\\"disallowed\\\"],[[12272,12283],\\\"disallowed\\\"],[[12284,12287],\\\"disallowed\\\"],[[12288,12288],\\\"disallowed_STD3_mapped\\\",[32]],[[12289,12289],\\\"valid\\\",[],\\\"NV8\\\"],[[12290,12290],\\\"mapped\\\",[46]],[[12291,12292],\\\"valid\\\",[],\\\"NV8\\\"],[[12293,12295],\\\"valid\\\"],[[12296,12329],\\\"valid\\\",[],\\\"NV8\\\"],[[12330,12333],\\\"valid\\\"],[[12334,12341],\\\"valid\\\",[],\\\"NV8\\\"],[[12342,12342],\\\"mapped\\\",[12306]],[[12343,12343],\\\"valid\\\",[],\\\"NV8\\\"],[[12344,12344],\\\"mapped\\\",[21313]],[[12345,12345],\\\"mapped\\\",[21316]],[[12346,12346],\\\"mapped\\\",[21317]],[[12347,12347],\\\"valid\\\",[],\\\"NV8\\\"],[[12348,12348],\\\"valid\\\"],[[12349,12349],\\\"valid\\\",[],\\\"NV8\\\"],[[12350,12350],\\\"valid\\\",[],\\\"NV8\\\"],[[12351,12351],\\\"valid\\\",[],\\\"NV8\\\"],[[12352,12352],\\\"disallowed\\\"],[[12353,12436],\\\"valid\\\"],[[12437,12438],\\\"valid\\\"],[[12439,12440],\\\"disallowed\\\"],[[12441,12442],\\\"valid\\\"],[[12443,12443],\\\"disallowed_STD3_mapped\\\",[32,12441]],[[12444,12444],\\\"disallowed_STD3_mapped\\\",[32,12442]],[[12445,12446],\\\"valid\\\"],[[12447,12447],\\\"mapped\\\",[12424,12426]],[[12448,12448],\\\"valid\\\",[],\\\"NV8\\\"],[[12449,12542],\\\"valid\\\"],[[12543,12543],\\\"mapped\\\",[12467,12488]],[[12544,12548],\\\"disallowed\\\"],[[12549,12588],\\\"valid\\\"],[[12589,12589],\\\"valid\\\"],[[12590,12592],\\\"disallowed\\\"],[[12593,12593],\\\"mapped\\\",[4352]],[[12594,12594],\\\"mapped\\\",[4353]],[[12595,12595],\\\"mapped\\\",[4522]],[[12596,12596],\\\"mapped\\\",[4354]],[[12597,12597],\\\"mapped\\\",[4524]],[[12598,12598],\\\"mapped\\\",[4525]],[[12599,12599],\\\"mapped\\\",[4355]],[[12600,12600],\\\"mapped\\\",[4356]],[[12601,12601],\\\"mapped\\\",[4357]],[[12602,12602],\\\"mapped\\\",[4528]],[[12603,12603],\\\"mapped\\\",[4529]],[[12604,12604],\\\"mapped\\\",[4530]],[[12605,12605],\\\"mapped\\\",[4531]],[[12606,12606],\\\"mapped\\\",[4532]],[[12607,12607],\\\"mapped\\\",[4533]],[[12608,12608],\\\"mapped\\\",[4378]],[[12609,12609],\\\"mapped\\\",[4358]],[[12610,12610],\\\"mapped\\\",[4359]],[[12611,12611],\\\"mapped\\\",[4360]],[[12612,12612],\\\"mapped\\\",[4385]],[[12613,12613],\\\"mapped\\\",[4361]],[[12614,12614],\\\"mapped\\\",[4362]],[[12615,12615],\\\"mapped\\\",[4363]],[[12616,12616],\\\"mapped\\\",[4364]],[[12617,12617],\\\"mapped\\\",[4365]],[[12618,12618],\\\"mapped\\\",[4366]],[[12619,12619],\\\"mapped\\\",[4367]],[[12620,12620],\\\"mapped\\\",[4368]],[[12621,12621],\\\"mapped\\\",[4369]],[[12622,12622],\\\"mapped\\\",[4370]],[[12623,12623],\\\"mapped\\\",[4449]],[[12624,12624],\\\"mapped\\\",[4450]],[[12625,12625],\\\"mapped\\\",[4451]],[[12626,12626],\\\"mapped\\\",[4452]],[[12627,12627],\\\"mapped\\\",[4453]],[[12628,12628],\\\"mapped\\\",[4454]],[[12629,12629],\\\"mapped\\\",[4455]],[[12630,12630],\\\"mapped\\\",[4456]],[[12631,12631],\\\"mapped\\\",[4457]],[[12632,12632],\\\"mapped\\\",[4458]],[[12633,12633],\\\"mapped\\\",[4459]],[[12634,12634],\\\"mapped\\\",[4460]],[[12635,12635],\\\"mapped\\\",[4461]],[[12636,12636],\\\"mapped\\\",[4462]],[[12637,12637],\\\"mapped\\\",[4463]],[[12638,12638],\\\"mapped\\\",[4464]],[[12639,12639],\\\"mapped\\\",[4465]],[[12640,12640],\\\"mapped\\\",[4466]],[[12641,12641],\\\"mapped\\\",[4467]],[[12642,12642],\\\"mapped\\\",[4468]],[[12643,12643],\\\"mapped\\\",[4469]],[[12644,12644],\\\"disallowed\\\"],[[12645,12645],\\\"mapped\\\",[4372]],[[12646,12646],\\\"mapped\\\",[4373]],[[12647,12647],\\\"mapped\\\",[4551]],[[12648,12648],\\\"mapped\\\",[4552]],[[12649,12649],\\\"mapped\\\",[4556]],[[12650,12650],\\\"mapped\\\",[4558]],[[12651,12651],\\\"mapped\\\",[4563]],[[12652,12652],\\\"mapped\\\",[4567]],[[12653,12653],\\\"mapped\\\",[4569]],[[12654,12654],\\\"mapped\\\",[4380]],[[12655,12655],\\\"mapped\\\",[4573]],[[12656,12656],\\\"mapped\\\",[4575]],[[12657,12657],\\\"mapped\\\",[4381]],[[12658,12658],\\\"mapped\\\",[4382]],[[12659,12659],\\\"mapped\\\",[4384]],[[12660,12660],\\\"mapped\\\",[4386]],[[12661,12661],\\\"mapped\\\",[4387]],[[12662,12662],\\\"mapped\\\",[4391]],[[12663,12663],\\\"mapped\\\",[4393]],[[12664,12664],\\\"mapped\\\",[4395]],[[12665,12665],\\\"mapped\\\",[4396]],[[12666,12666],\\\"mapped\\\",[4397]],[[12667,12667],\\\"mapped\\\",[4398]],[[12668,12668],\\\"mapped\\\",[4399]],[[12669,12669],\\\"mapped\\\",[4402]],[[12670,12670],\\\"mapped\\\",[4406]],[[12671,12671],\\\"mapped\\\",[4416]],[[12672,12672],\\\"mapped\\\",[4423]],[[12673,12673],\\\"mapped\\\",[4428]],[[12674,12674],\\\"mapped\\\",[4593]],[[12675,12675],\\\"mapped\\\",[4594]],[[12676,12676],\\\"mapped\\\",[4439]],[[12677,12677],\\\"mapped\\\",[4440]],[[12678,12678],\\\"mapped\\\",[4441]],[[12679,12679],\\\"mapped\\\",[4484]],[[12680,12680],\\\"mapped\\\",[4485]],[[12681,12681],\\\"mapped\\\",[4488]],[[12682,12682],\\\"mapped\\\",[4497]],[[12683,12683],\\\"mapped\\\",[4498]],[[12684,12684],\\\"mapped\\\",[4500]],[[12685,12685],\\\"mapped\\\",[4510]],[[12686,12686],\\\"mapped\\\",[4513]],[[12687,12687],\\\"disallowed\\\"],[[12688,12689],\\\"valid\\\",[],\\\"NV8\\\"],[[12690,12690],\\\"mapped\\\",[19968]],[[12691,12691],\\\"mapped\\\",[20108]],[[12692,12692],\\\"mapped\\\",[19977]],[[12693,12693],\\\"mapped\\\",[22235]],[[12694,12694],\\\"mapped\\\",[19978]],[[12695,12695],\\\"mapped\\\",[20013]],[[12696,12696],\\\"mapped\\\",[19979]],[[12697,12697],\\\"mapped\\\",[30002]],[[12698,12698],\\\"mapped\\\",[20057]],[[12699,12699],\\\"mapped\\\",[19993]],[[12700,12700],\\\"mapped\\\",[19969]],[[12701,12701],\\\"mapped\\\",[22825]],[[12702,12702],\\\"mapped\\\",[22320]],[[12703,12703],\\\"mapped\\\",[20154]],[[12704,12727],\\\"valid\\\"],[[12728,12730],\\\"valid\\\"],[[12731,12735],\\\"disallowed\\\"],[[12736,12751],\\\"valid\\\",[],\\\"NV8\\\"],[[12752,12771],\\\"valid\\\",[],\\\"NV8\\\"],[[12772,12783],\\\"disallowed\\\"],[[12784,12799],\\\"valid\\\"],[[12800,12800],\\\"disallowed_STD3_mapped\\\",[40,4352,41]],[[12801,12801],\\\"disallowed_STD3_mapped\\\",[40,4354,41]],[[12802,12802],\\\"disallowed_STD3_mapped\\\",[40,4355,41]],[[12803,12803],\\\"disallowed_STD3_mapped\\\",[40,4357,41]],[[12804,12804],\\\"disallowed_STD3_mapped\\\",[40,4358,41]],[[12805,12805],\\\"disallowed_STD3_mapped\\\",[40,4359,41]],[[12806,12806],\\\"disallowed_STD3_mapped\\\",[40,4361,41]],[[12807,12807],\\\"disallowed_STD3_mapped\\\",[40,4363,41]],[[12808,12808],\\\"disallowed_STD3_mapped\\\",[40,4364,41]],[[12809,12809],\\\"disallowed_STD3_mapped\\\",[40,4366,41]],[[12810,12810],\\\"disallowed_STD3_mapped\\\",[40,4367,41]],[[12811,12811],\\\"disallowed_STD3_mapped\\\",[40,4368,41]],[[12812,12812],\\\"disallowed_STD3_mapped\\\",[40,4369,41]],[[12813,12813],\\\"disallowed_STD3_mapped\\\",[40,4370,41]],[[12814,12814],\\\"disallowed_STD3_mapped\\\",[40,44032,41]],[[12815,12815],\\\"disallowed_STD3_mapped\\\",[40,45208,41]],[[12816,12816],\\\"disallowed_STD3_mapped\\\",[40,45796,41]],[[12817,12817],\\\"disallowed_STD3_mapped\\\",[40,46972,41]],[[12818,12818],\\\"disallowed_STD3_mapped\\\",[40,47560,41]],[[12819,12819],\\\"disallowed_STD3_mapped\\\",[40,48148,41]],[[12820,12820],\\\"disallowed_STD3_mapped\\\",[40,49324,41]],[[12821,12821],\\\"disallowed_STD3_mapped\\\",[40,50500,41]],[[12822,12822],\\\"disallowed_STD3_mapped\\\",[40,51088,41]],[[12823,12823],\\\"disallowed_STD3_mapped\\\",[40,52264,41]],[[12824,12824],\\\"disallowed_STD3_mapped\\\",[40,52852,41]],[[12825,12825],\\\"disallowed_STD3_mapped\\\",[40,53440,41]],[[12826,12826],\\\"disallowed_STD3_mapped\\\",[40,54028,41]],[[12827,12827],\\\"disallowed_STD3_mapped\\\",[40,54616,41]],[[12828,12828],\\\"disallowed_STD3_mapped\\\",[40,51452,41]],[[12829,12829],\\\"disallowed_STD3_mapped\\\",[40,50724,51204,41]],[[12830,12830],\\\"disallowed_STD3_mapped\\\",[40,50724,54980,41]],[[12831,12831],\\\"disallowed\\\"],[[12832,12832],\\\"disallowed_STD3_mapped\\\",[40,19968,41]],[[12833,12833],\\\"disallowed_STD3_mapped\\\",[40,20108,41]],[[12834,12834],\\\"disallowed_STD3_mapped\\\",[40,19977,41]],[[12835,12835],\\\"disallowed_STD3_mapped\\\",[40,22235,41]],[[12836,12836],\\\"disallowed_STD3_mapped\\\",[40,20116,41]],[[12837,12837],\\\"disallowed_STD3_mapped\\\",[40,20845,41]],[[12838,12838],\\\"disallowed_STD3_mapped\\\",[40,19971,41]],[[12839,12839],\\\"disallowed_STD3_mapped\\\",[40,20843,41]],[[12840,12840],\\\"disallowed_STD3_mapped\\\",[40,20061,41]],[[12841,12841],\\\"disallowed_STD3_mapped\\\",[40,21313,41]],[[12842,12842],\\\"disallowed_STD3_mapped\\\",[40,26376,41]],[[12843,12843],\\\"disallowed_STD3_mapped\\\",[40,28779,41]],[[12844,12844],\\\"disallowed_STD3_mapped\\\",[40,27700,41]],[[12845,12845],\\\"disallowed_STD3_mapped\\\",[40,26408,41]],[[12846,12846],\\\"disallowed_STD3_mapped\\\",[40,37329,41]],[[12847,12847],\\\"disallowed_STD3_mapped\\\",[40,22303,41]],[[12848,12848],\\\"disallowed_STD3_mapped\\\",[40,26085,41]],[[12849,12849],\\\"disallowed_STD3_mapped\\\",[40,26666,41]],[[12850,12850],\\\"disallowed_STD3_mapped\\\",[40,26377,41]],[[12851,12851],\\\"disallowed_STD3_mapped\\\",[40,31038,41]],[[12852,12852],\\\"disallowed_STD3_mapped\\\",[40,21517,41]],[[12853,12853],\\\"disallowed_STD3_mapped\\\",[40,29305,41]],[[12854,12854],\\\"disallowed_STD3_mapped\\\",[40,36001,41]],[[12855,12855],\\\"disallowed_STD3_mapped\\\",[40,31069,41]],[[12856,12856],\\\"disallowed_STD3_mapped\\\",[40,21172,41]],[[12857,12857],\\\"disallowed_STD3_mapped\\\",[40,20195,41]],[[12858,12858],\\\"disallowed_STD3_mapped\\\",[40,21628,41]],[[12859,12859],\\\"disallowed_STD3_mapped\\\",[40,23398,41]],[[12860,12860],\\\"disallowed_STD3_mapped\\\",[40,30435,41]],[[12861,12861],\\\"disallowed_STD3_mapped\\\",[40,20225,41]],[[12862,12862],\\\"disallowed_STD3_mapped\\\",[40,36039,41]],[[12863,12863],\\\"disallowed_STD3_mapped\\\",[40,21332,41]],[[12864,12864],\\\"disallowed_STD3_mapped\\\",[40,31085,41]],[[12865,12865],\\\"disallowed_STD3_mapped\\\",[40,20241,41]],[[12866,12866],\\\"disallowed_STD3_mapped\\\",[40,33258,41]],[[12867,12867],\\\"disallowed_STD3_mapped\\\",[40,33267,41]],[[12868,12868],\\\"mapped\\\",[21839]],[[12869,12869],\\\"mapped\\\",[24188]],[[12870,12870],\\\"mapped\\\",[25991]],[[12871,12871],\\\"mapped\\\",[31631]],[[12872,12879],\\\"valid\\\",[],\\\"NV8\\\"],[[12880,12880],\\\"mapped\\\",[112,116,101]],[[12881,12881],\\\"mapped\\\",[50,49]],[[12882,12882],\\\"mapped\\\",[50,50]],[[12883,12883],\\\"mapped\\\",[50,51]],[[12884,12884],\\\"mapped\\\",[50,52]],[[12885,12885],\\\"mapped\\\",[50,53]],[[12886,12886],\\\"mapped\\\",[50,54]],[[12887,12887],\\\"mapped\\\",[50,55]],[[12888,12888],\\\"mapped\\\",[50,56]],[[12889,12889],\\\"mapped\\\",[50,57]],[[12890,12890],\\\"mapped\\\",[51,48]],[[12891,12891],\\\"mapped\\\",[51,49]],[[12892,12892],\\\"mapped\\\",[51,50]],[[12893,12893],\\\"mapped\\\",[51,51]],[[12894,12894],\\\"mapped\\\",[51,52]],[[12895,12895],\\\"mapped\\\",[51,53]],[[12896,12896],\\\"mapped\\\",[4352]],[[12897,12897],\\\"mapped\\\",[4354]],[[12898,12898],\\\"mapped\\\",[4355]],[[12899,12899],\\\"mapped\\\",[4357]],[[12900,12900],\\\"mapped\\\",[4358]],[[12901,12901],\\\"mapped\\\",[4359]],[[12902,12902],\\\"mapped\\\",[4361]],[[12903,12903],\\\"mapped\\\",[4363]],[[12904,12904],\\\"mapped\\\",[4364]],[[12905,12905],\\\"mapped\\\",[4366]],[[12906,12906],\\\"mapped\\\",[4367]],[[12907,12907],\\\"mapped\\\",[4368]],[[12908,12908],\\\"mapped\\\",[4369]],[[12909,12909],\\\"mapped\\\",[4370]],[[12910,12910],\\\"mapped\\\",[44032]],[[12911,12911],\\\"mapped\\\",[45208]],[[12912,12912],\\\"mapped\\\",[45796]],[[12913,12913],\\\"mapped\\\",[46972]],[[12914,12914],\\\"mapped\\\",[47560]],[[12915,12915],\\\"mapped\\\",[48148]],[[12916,12916],\\\"mapped\\\",[49324]],[[12917,12917],\\\"mapped\\\",[50500]],[[12918,12918],\\\"mapped\\\",[51088]],[[12919,12919],\\\"mapped\\\",[52264]],[[12920,12920],\\\"mapped\\\",[52852]],[[12921,12921],\\\"mapped\\\",[53440]],[[12922,12922],\\\"mapped\\\",[54028]],[[12923,12923],\\\"mapped\\\",[54616]],[[12924,12924],\\\"mapped\\\",[52280,44256]],[[12925,12925],\\\"mapped\\\",[51452,51032]],[[12926,12926],\\\"mapped\\\",[50864]],[[12927,12927],\\\"valid\\\",[],\\\"NV8\\\"],[[12928,12928],\\\"mapped\\\",[19968]],[[12929,12929],\\\"mapped\\\",[20108]],[[12930,12930],\\\"mapped\\\",[19977]],[[12931,12931],\\\"mapped\\\",[22235]],[[12932,12932],\\\"mapped\\\",[20116]],[[12933,12933],\\\"mapped\\\",[20845]],[[12934,12934],\\\"mapped\\\",[19971]],[[12935,12935],\\\"mapped\\\",[20843]],[[12936,12936],\\\"mapped\\\",[20061]],[[12937,12937],\\\"mapped\\\",[21313]],[[12938,12938],\\\"mapped\\\",[26376]],[[12939,12939],\\\"mapped\\\",[28779]],[[12940,12940],\\\"mapped\\\",[27700]],[[12941,12941],\\\"mapped\\\",[26408]],[[12942,12942],\\\"mapped\\\",[37329]],[[12943,12943],\\\"mapped\\\",[22303]],[[12944,12944],\\\"mapped\\\",[26085]],[[12945,12945],\\\"mapped\\\",[26666]],[[12946,12946],\\\"mapped\\\",[26377]],[[12947,12947],\\\"mapped\\\",[31038]],[[12948,12948],\\\"mapped\\\",[21517]],[[12949,12949],\\\"mapped\\\",[29305]],[[12950,12950],\\\"mapped\\\",[36001]],[[12951,12951],\\\"mapped\\\",[31069]],[[12952,12952],\\\"mapped\\\",[21172]],[[12953,12953],\\\"mapped\\\",[31192]],[[12954,12954],\\\"mapped\\\",[30007]],[[12955,12955],\\\"mapped\\\",[22899]],[[12956,12956],\\\"mapped\\\",[36969]],[[12957,12957],\\\"mapped\\\",[20778]],[[12958,12958],\\\"mapped\\\",[21360]],[[12959,12959],\\\"mapped\\\",[27880]],[[12960,12960],\\\"mapped\\\",[38917]],[[12961,12961],\\\"mapped\\\",[20241]],[[12962,12962],\\\"mapped\\\",[20889]],[[12963,12963],\\\"mapped\\\",[27491]],[[12964,12964],\\\"mapped\\\",[19978]],[[12965,12965],\\\"mapped\\\",[20013]],[[12966,12966],\\\"mapped\\\",[19979]],[[12967,12967],\\\"mapped\\\",[24038]],[[12968,12968],\\\"mapped\\\",[21491]],[[12969,12969],\\\"mapped\\\",[21307]],[[12970,12970],\\\"mapped\\\",[23447]],[[12971,12971],\\\"mapped\\\",[23398]],[[12972,12972],\\\"mapped\\\",[30435]],[[12973,12973],\\\"mapped\\\",[20225]],[[12974,12974],\\\"mapped\\\",[36039]],[[12975,12975],\\\"mapped\\\",[21332]],[[12976,12976],\\\"mapped\\\",[22812]],[[12977,12977],\\\"mapped\\\",[51,54]],[[12978,12978],\\\"mapped\\\",[51,55]],[[12979,12979],\\\"mapped\\\",[51,56]],[[12980,12980],\\\"mapped\\\",[51,57]],[[12981,12981],\\\"mapped\\\",[52,48]],[[12982,12982],\\\"mapped\\\",[52,49]],[[12983,12983],\\\"mapped\\\",[52,50]],[[12984,12984],\\\"mapped\\\",[52,51]],[[12985,12985],\\\"mapped\\\",[52,52]],[[12986,12986],\\\"mapped\\\",[52,53]],[[12987,12987],\\\"mapped\\\",[52,54]],[[12988,12988],\\\"mapped\\\",[52,55]],[[12989,12989],\\\"mapped\\\",[52,56]],[[12990,12990],\\\"mapped\\\",[52,57]],[[12991,12991],\\\"mapped\\\",[53,48]],[[12992,12992],\\\"mapped\\\",[49,26376]],[[12993,12993],\\\"mapped\\\",[50,26376]],[[12994,12994],\\\"mapped\\\",[51,26376]],[[12995,12995],\\\"mapped\\\",[52,26376]],[[12996,12996],\\\"mapped\\\",[53,26376]],[[12997,12997],\\\"mapped\\\",[54,26376]],[[12998,12998],\\\"mapped\\\",[55,26376]],[[12999,12999],\\\"mapped\\\",[56,26376]],[[13000,13000],\\\"mapped\\\",[57,26376]],[[13001,13001],\\\"mapped\\\",[49,48,26376]],[[13002,13002],\\\"mapped\\\",[49,49,26376]],[[13003,13003],\\\"mapped\\\",[49,50,26376]],[[13004,13004],\\\"mapped\\\",[104,103]],[[13005,13005],\\\"mapped\\\",[101,114,103]],[[13006,13006],\\\"mapped\\\",[101,118]],[[13007,13007],\\\"mapped\\\",[108,116,100]],[[13008,13008],\\\"mapped\\\",[12450]],[[13009,13009],\\\"mapped\\\",[12452]],[[13010,13010],\\\"mapped\\\",[12454]],[[13011,13011],\\\"mapped\\\",[12456]],[[13012,13012],\\\"mapped\\\",[12458]],[[13013,13013],\\\"mapped\\\",[12459]],[[13014,13014],\\\"mapped\\\",[12461]],[[13015,13015],\\\"mapped\\\",[12463]],[[13016,13016],\\\"mapped\\\",[12465]],[[13017,13017],\\\"mapped\\\",[12467]],[[13018,13018],\\\"mapped\\\",[12469]],[[13019,13019],\\\"mapped\\\",[12471]],[[13020,13020],\\\"mapped\\\",[12473]],[[13021,13021],\\\"mapped\\\",[12475]],[[13022,13022],\\\"mapped\\\",[12477]],[[13023,13023],\\\"mapped\\\",[12479]],[[13024,13024],\\\"mapped\\\",[12481]],[[13025,13025],\\\"mapped\\\",[12484]],[[13026,13026],\\\"mapped\\\",[12486]],[[13027,13027],\\\"mapped\\\",[12488]],[[13028,13028],\\\"mapped\\\",[12490]],[[13029,13029],\\\"mapped\\\",[12491]],[[13030,13030],\\\"mapped\\\",[12492]],[[13031,13031],\\\"mapped\\\",[12493]],[[13032,13032],\\\"mapped\\\",[12494]],[[13033,13033],\\\"mapped\\\",[12495]],[[13034,13034],\\\"mapped\\\",[12498]],[[13035,13035],\\\"mapped\\\",[12501]],[[13036,13036],\\\"mapped\\\",[12504]],[[13037,13037],\\\"mapped\\\",[12507]],[[13038,13038],\\\"mapped\\\",[12510]],[[13039,13039],\\\"mapped\\\",[12511]],[[13040,13040],\\\"mapped\\\",[12512]],[[13041,13041],\\\"mapped\\\",[12513]],[[13042,13042],\\\"mapped\\\",[12514]],[[13043,13043],\\\"mapped\\\",[12516]],[[13044,13044],\\\"mapped\\\",[12518]],[[13045,13045],\\\"mapped\\\",[12520]],[[13046,13046],\\\"mapped\\\",[12521]],[[13047,13047],\\\"mapped\\\",[12522]],[[13048,13048],\\\"mapped\\\",[12523]],[[13049,13049],\\\"mapped\\\",[12524]],[[13050,13050],\\\"mapped\\\",[12525]],[[13051,13051],\\\"mapped\\\",[12527]],[[13052,13052],\\\"mapped\\\",[12528]],[[13053,13053],\\\"mapped\\\",[12529]],[[13054,13054],\\\"mapped\\\",[12530]],[[13055,13055],\\\"disallowed\\\"],[[13056,13056],\\\"mapped\\\",[12450,12497,12540,12488]],[[13057,13057],\\\"mapped\\\",[12450,12523,12501,12449]],[[13058,13058],\\\"mapped\\\",[12450,12531,12506,12450]],[[13059,13059],\\\"mapped\\\",[12450,12540,12523]],[[13060,13060],\\\"mapped\\\",[12452,12491,12531,12464]],[[13061,13061],\\\"mapped\\\",[12452,12531,12481]],[[13062,13062],\\\"mapped\\\",[12454,12457,12531]],[[13063,13063],\\\"mapped\\\",[12456,12473,12463,12540,12489]],[[13064,13064],\\\"mapped\\\",[12456,12540,12459,12540]],[[13065,13065],\\\"mapped\\\",[12458,12531,12473]],[[13066,13066],\\\"mapped\\\",[12458,12540,12512]],[[13067,13067],\\\"mapped\\\",[12459,12452,12522]],[[13068,13068],\\\"mapped\\\",[12459,12521,12483,12488]],[[13069,13069],\\\"mapped\\\",[12459,12525,12522,12540]],[[13070,13070],\\\"mapped\\\",[12460,12525,12531]],[[13071,13071],\\\"mapped\\\",[12460,12531,12510]],[[13072,13072],\\\"mapped\\\",[12462,12460]],[[13073,13073],\\\"mapped\\\",[12462,12491,12540]],[[13074,13074],\\\"mapped\\\",[12461,12517,12522,12540]],[[13075,13075],\\\"mapped\\\",[12462,12523,12480,12540]],[[13076,13076],\\\"mapped\\\",[12461,12525]],[[13077,13077],\\\"mapped\\\",[12461,12525,12464,12521,12512]],[[13078,13078],\\\"mapped\\\",[12461,12525,12513,12540,12488,12523]],[[13079,13079],\\\"mapped\\\",[12461,12525,12527,12483,12488]],[[13080,13080],\\\"mapped\\\",[12464,12521,12512]],[[13081,13081],\\\"mapped\\\",[12464,12521,12512,12488,12531]],[[13082,13082],\\\"mapped\\\",[12463,12523,12476,12452,12525]],[[13083,13083],\\\"mapped\\\",[12463,12525,12540,12493]],[[13084,13084],\\\"mapped\\\",[12465,12540,12473]],[[13085,13085],\\\"mapped\\\",[12467,12523,12490]],[[13086,13086],\\\"mapped\\\",[12467,12540,12509]],[[13087,13087],\\\"mapped\\\",[12469,12452,12463,12523]],[[13088,13088],\\\"mapped\\\",[12469,12531,12481,12540,12512]],[[13089,13089],\\\"mapped\\\",[12471,12522,12531,12464]],[[13090,13090],\\\"mapped\\\",[12475,12531,12481]],[[13091,13091],\\\"mapped\\\",[12475,12531,12488]],[[13092,13092],\\\"mapped\\\",[12480,12540,12473]],[[13093,13093],\\\"mapped\\\",[12487,12471]],[[13094,13094],\\\"mapped\\\",[12489,12523]],[[13095,13095],\\\"mapped\\\",[12488,12531]],[[13096,13096],\\\"mapped\\\",[12490,12494]],[[13097,13097],\\\"mapped\\\",[12494,12483,12488]],[[13098,13098],\\\"mapped\\\",[12495,12452,12484]],[[13099,13099],\\\"mapped\\\",[12497,12540,12475,12531,12488]],[[13100,13100],\\\"mapped\\\",[12497,12540,12484]],[[13101,13101],\\\"mapped\\\",[12496,12540,12524,12523]],[[13102,13102],\\\"mapped\\\",[12500,12450,12473,12488,12523]],[[13103,13103],\\\"mapped\\\",[12500,12463,12523]],[[13104,13104],\\\"mapped\\\",[12500,12467]],[[13105,13105],\\\"mapped\\\",[12499,12523]],[[13106,13106],\\\"mapped\\\",[12501,12449,12521,12483,12489]],[[13107,13107],\\\"mapped\\\",[12501,12451,12540,12488]],[[13108,13108],\\\"mapped\\\",[12502,12483,12471,12455,12523]],[[13109,13109],\\\"mapped\\\",[12501,12521,12531]],[[13110,13110],\\\"mapped\\\",[12504,12463,12479,12540,12523]],[[13111,13111],\\\"mapped\\\",[12506,12477]],[[13112,13112],\\\"mapped\\\",[12506,12491,12498]],[[13113,13113],\\\"mapped\\\",[12504,12523,12484]],[[13114,13114],\\\"mapped\\\",[12506,12531,12473]],[[13115,13115],\\\"mapped\\\",[12506,12540,12472]],[[13116,13116],\\\"mapped\\\",[12505,12540,12479]],[[13117,13117],\\\"mapped\\\",[12509,12452,12531,12488]],[[13118,13118],\\\"mapped\\\",[12508,12523,12488]],[[13119,13119],\\\"mapped\\\",[12507,12531]],[[13120,13120],\\\"mapped\\\",[12509,12531,12489]],[[13121,13121],\\\"mapped\\\",[12507,12540,12523]],[[13122,13122],\\\"mapped\\\",[12507,12540,12531]],[[13123,13123],\\\"mapped\\\",[12510,12452,12463,12525]],[[13124,13124],\\\"mapped\\\",[12510,12452,12523]],[[13125,13125],\\\"mapped\\\",[12510,12483,12495]],[[13126,13126],\\\"mapped\\\",[12510,12523,12463]],[[13127,13127],\\\"mapped\\\",[12510,12531,12471,12519,12531]],[[13128,13128],\\\"mapped\\\",[12511,12463,12525,12531]],[[13129,13129],\\\"mapped\\\",[12511,12522]],[[13130,13130],\\\"mapped\\\",[12511,12522,12496,12540,12523]],[[13131,13131],\\\"mapped\\\",[12513,12460]],[[13132,13132],\\\"mapped\\\",[12513,12460,12488,12531]],[[13133,13133],\\\"mapped\\\",[12513,12540,12488,12523]],[[13134,13134],\\\"mapped\\\",[12516,12540,12489]],[[13135,13135],\\\"mapped\\\",[12516,12540,12523]],[[13136,13136],\\\"mapped\\\",[12518,12450,12531]],[[13137,13137],\\\"mapped\\\",[12522,12483,12488,12523]],[[13138,13138],\\\"mapped\\\",[12522,12521]],[[13139,13139],\\\"mapped\\\",[12523,12500,12540]],[[13140,13140],\\\"mapped\\\",[12523,12540,12502,12523]],[[13141,13141],\\\"mapped\\\",[12524,12512]],[[13142,13142],\\\"mapped\\\",[12524,12531,12488,12466,12531]],[[13143,13143],\\\"mapped\\\",[12527,12483,12488]],[[13144,13144],\\\"mapped\\\",[48,28857]],[[13145,13145],\\\"mapped\\\",[49,28857]],[[13146,13146],\\\"mapped\\\",[50,28857]],[[13147,13147],\\\"mapped\\\",[51,28857]],[[13148,13148],\\\"mapped\\\",[52,28857]],[[13149,13149],\\\"mapped\\\",[53,28857]],[[13150,13150],\\\"mapped\\\",[54,28857]],[[13151,13151],\\\"mapped\\\",[55,28857]],[[13152,13152],\\\"mapped\\\",[56,28857]],[[13153,13153],\\\"mapped\\\",[57,28857]],[[13154,13154],\\\"mapped\\\",[49,48,28857]],[[13155,13155],\\\"mapped\\\",[49,49,28857]],[[13156,13156],\\\"mapped\\\",[49,50,28857]],[[13157,13157],\\\"mapped\\\",[49,51,28857]],[[13158,13158],\\\"mapped\\\",[49,52,28857]],[[13159,13159],\\\"mapped\\\",[49,53,28857]],[[13160,13160],\\\"mapped\\\",[49,54,28857]],[[13161,13161],\\\"mapped\\\",[49,55,28857]],[[13162,13162],\\\"mapped\\\",[49,56,28857]],[[13163,13163],\\\"mapped\\\",[49,57,28857]],[[13164,13164],\\\"mapped\\\",[50,48,28857]],[[13165,13165],\\\"mapped\\\",[50,49,28857]],[[13166,13166],\\\"mapped\\\",[50,50,28857]],[[13167,13167],\\\"mapped\\\",[50,51,28857]],[[13168,13168],\\\"mapped\\\",[50,52,28857]],[[13169,13169],\\\"mapped\\\",[104,112,97]],[[13170,13170],\\\"mapped\\\",[100,97]],[[13171,13171],\\\"mapped\\\",[97,117]],[[13172,13172],\\\"mapped\\\",[98,97,114]],[[13173,13173],\\\"mapped\\\",[111,118]],[[13174,13174],\\\"mapped\\\",[112,99]],[[13175,13175],\\\"mapped\\\",[100,109]],[[13176,13176],\\\"mapped\\\",[100,109,50]],[[13177,13177],\\\"mapped\\\",[100,109,51]],[[13178,13178],\\\"mapped\\\",[105,117]],[[13179,13179],\\\"mapped\\\",[24179,25104]],[[13180,13180],\\\"mapped\\\",[26157,21644]],[[13181,13181],\\\"mapped\\\",[22823,27491]],[[13182,13182],\\\"mapped\\\",[26126,27835]],[[13183,13183],\\\"mapped\\\",[26666,24335,20250,31038]],[[13184,13184],\\\"mapped\\\",[112,97]],[[13185,13185],\\\"mapped\\\",[110,97]],[[13186,13186],\\\"mapped\\\",[956,97]],[[13187,13187],\\\"mapped\\\",[109,97]],[[13188,13188],\\\"mapped\\\",[107,97]],[[13189,13189],\\\"mapped\\\",[107,98]],[[13190,13190],\\\"mapped\\\",[109,98]],[[13191,13191],\\\"mapped\\\",[103,98]],[[13192,13192],\\\"mapped\\\",[99,97,108]],[[13193,13193],\\\"mapped\\\",[107,99,97,108]],[[13194,13194],\\\"mapped\\\",[112,102]],[[13195,13195],\\\"mapped\\\",[110,102]],[[13196,13196],\\\"mapped\\\",[956,102]],[[13197,13197],\\\"mapped\\\",[956,103]],[[13198,13198],\\\"mapped\\\",[109,103]],[[13199,13199],\\\"mapped\\\",[107,103]],[[13200,13200],\\\"mapped\\\",[104,122]],[[13201,13201],\\\"mapped\\\",[107,104,122]],[[13202,13202],\\\"mapped\\\",[109,104,122]],[[13203,13203],\\\"mapped\\\",[103,104,122]],[[13204,13204],\\\"mapped\\\",[116,104,122]],[[13205,13205],\\\"mapped\\\",[956,108]],[[13206,13206],\\\"mapped\\\",[109,108]],[[13207,13207],\\\"mapped\\\",[100,108]],[[13208,13208],\\\"mapped\\\",[107,108]],[[13209,13209],\\\"mapped\\\",[102,109]],[[13210,13210],\\\"mapped\\\",[110,109]],[[13211,13211],\\\"mapped\\\",[956,109]],[[13212,13212],\\\"mapped\\\",[109,109]],[[13213,13213],\\\"mapped\\\",[99,109]],[[13214,13214],\\\"mapped\\\",[107,109]],[[13215,13215],\\\"mapped\\\",[109,109,50]],[[13216,13216],\\\"mapped\\\",[99,109,50]],[[13217,13217],\\\"mapped\\\",[109,50]],[[13218,13218],\\\"mapped\\\",[107,109,50]],[[13219,13219],\\\"mapped\\\",[109,109,51]],[[13220,13220],\\\"mapped\\\",[99,109,51]],[[13221,13221],\\\"mapped\\\",[109,51]],[[13222,13222],\\\"mapped\\\",[107,109,51]],[[13223,13223],\\\"mapped\\\",[109,8725,115]],[[13224,13224],\\\"mapped\\\",[109,8725,115,50]],[[13225,13225],\\\"mapped\\\",[112,97]],[[13226,13226],\\\"mapped\\\",[107,112,97]],[[13227,13227],\\\"mapped\\\",[109,112,97]],[[13228,13228],\\\"mapped\\\",[103,112,97]],[[13229,13229],\\\"mapped\\\",[114,97,100]],[[13230,13230],\\\"mapped\\\",[114,97,100,8725,115]],[[13231,13231],\\\"mapped\\\",[114,97,100,8725,115,50]],[[13232,13232],\\\"mapped\\\",[112,115]],[[13233,13233],\\\"mapped\\\",[110,115]],[[13234,13234],\\\"mapped\\\",[956,115]],[[13235,13235],\\\"mapped\\\",[109,115]],[[13236,13236],\\\"mapped\\\",[112,118]],[[13237,13237],\\\"mapped\\\",[110,118]],[[13238,13238],\\\"mapped\\\",[956,118]],[[13239,13239],\\\"mapped\\\",[109,118]],[[13240,13240],\\\"mapped\\\",[107,118]],[[13241,13241],\\\"mapped\\\",[109,118]],[[13242,13242],\\\"mapped\\\",[112,119]],[[13243,13243],\\\"mapped\\\",[110,119]],[[13244,13244],\\\"mapped\\\",[956,119]],[[13245,13245],\\\"mapped\\\",[109,119]],[[13246,13246],\\\"mapped\\\",[107,119]],[[13247,13247],\\\"mapped\\\",[109,119]],[[13248,13248],\\\"mapped\\\",[107,969]],[[13249,13249],\\\"mapped\\\",[109,969]],[[13250,13250],\\\"disallowed\\\"],[[13251,13251],\\\"mapped\\\",[98,113]],[[13252,13252],\\\"mapped\\\",[99,99]],[[13253,13253],\\\"mapped\\\",[99,100]],[[13254,13254],\\\"mapped\\\",[99,8725,107,103]],[[13255,13255],\\\"disallowed\\\"],[[13256,13256],\\\"mapped\\\",[100,98]],[[13257,13257],\\\"mapped\\\",[103,121]],[[13258,13258],\\\"mapped\\\",[104,97]],[[13259,13259],\\\"mapped\\\",[104,112]],[[13260,13260],\\\"mapped\\\",[105,110]],[[13261,13261],\\\"mapped\\\",[107,107]],[[13262,13262],\\\"mapped\\\",[107,109]],[[13263,13263],\\\"mapped\\\",[107,116]],[[13264,13264],\\\"mapped\\\",[108,109]],[[13265,13265],\\\"mapped\\\",[108,110]],[[13266,13266],\\\"mapped\\\",[108,111,103]],[[13267,13267],\\\"mapped\\\",[108,120]],[[13268,13268],\\\"mapped\\\",[109,98]],[[13269,13269],\\\"mapped\\\",[109,105,108]],[[13270,13270],\\\"mapped\\\",[109,111,108]],[[13271,13271],\\\"mapped\\\",[112,104]],[[13272,13272],\\\"disallowed\\\"],[[13273,13273],\\\"mapped\\\",[112,112,109]],[[13274,13274],\\\"mapped\\\",[112,114]],[[13275,13275],\\\"mapped\\\",[115,114]],[[13276,13276],\\\"mapped\\\",[115,118]],[[13277,13277],\\\"mapped\\\",[119,98]],[[13278,13278],\\\"mapped\\\",[118,8725,109]],[[13279,13279],\\\"mapped\\\",[97,8725,109]],[[13280,13280],\\\"mapped\\\",[49,26085]],[[13281,13281],\\\"mapped\\\",[50,26085]],[[13282,13282],\\\"mapped\\\",[51,26085]],[[13283,13283],\\\"mapped\\\",[52,26085]],[[13284,13284],\\\"mapped\\\",[53,26085]],[[13285,13285],\\\"mapped\\\",[54,26085]],[[13286,13286],\\\"mapped\\\",[55,26085]],[[13287,13287],\\\"mapped\\\",[56,26085]],[[13288,13288],\\\"mapped\\\",[57,26085]],[[13289,13289],\\\"mapped\\\",[49,48,26085]],[[13290,13290],\\\"mapped\\\",[49,49,26085]],[[13291,13291],\\\"mapped\\\",[49,50,26085]],[[13292,13292],\\\"mapped\\\",[49,51,26085]],[[13293,13293],\\\"mapped\\\",[49,52,26085]],[[13294,13294],\\\"mapped\\\",[49,53,26085]],[[13295,13295],\\\"mapped\\\",[49,54,26085]],[[13296,13296],\\\"mapped\\\",[49,55,26085]],[[13297,13297],\\\"mapped\\\",[49,56,26085]],[[13298,13298],\\\"mapped\\\",[49,57,26085]],[[13299,13299],\\\"mapped\\\",[50,48,26085]],[[13300,13300],\\\"mapped\\\",[50,49,26085]],[[13301,13301],\\\"mapped\\\",[50,50,26085]],[[13302,13302],\\\"mapped\\\",[50,51,26085]],[[13303,13303],\\\"mapped\\\",[50,52,26085]],[[13304,13304],\\\"mapped\\\",[50,53,26085]],[[13305,13305],\\\"mapped\\\",[50,54,26085]],[[13306,13306],\\\"mapped\\\",[50,55,26085]],[[13307,13307],\\\"mapped\\\",[50,56,26085]],[[13308,13308],\\\"mapped\\\",[50,57,26085]],[[13309,13309],\\\"mapped\\\",[51,48,26085]],[[13310,13310],\\\"mapped\\\",[51,49,26085]],[[13311,13311],\\\"mapped\\\",[103,97,108]],[[13312,19893],\\\"valid\\\"],[[19894,19903],\\\"disallowed\\\"],[[19904,19967],\\\"valid\\\",[],\\\"NV8\\\"],[[19968,40869],\\\"valid\\\"],[[40870,40891],\\\"valid\\\"],[[40892,40899],\\\"valid\\\"],[[40900,40907],\\\"valid\\\"],[[40908,40908],\\\"valid\\\"],[[40909,40917],\\\"valid\\\"],[[40918,40959],\\\"disallowed\\\"],[[40960,42124],\\\"valid\\\"],[[42125,42127],\\\"disallowed\\\"],[[42128,42145],\\\"valid\\\",[],\\\"NV8\\\"],[[42146,42147],\\\"valid\\\",[],\\\"NV8\\\"],[[42148,42163],\\\"valid\\\",[],\\\"NV8\\\"],[[42164,42164],\\\"valid\\\",[],\\\"NV8\\\"],[[42165,42176],\\\"valid\\\",[],\\\"NV8\\\"],[[42177,42177],\\\"valid\\\",[],\\\"NV8\\\"],[[42178,42180],\\\"valid\\\",[],\\\"NV8\\\"],[[42181,42181],\\\"valid\\\",[],\\\"NV8\\\"],[[42182,42182],\\\"valid\\\",[],\\\"NV8\\\"],[[42183,42191],\\\"disallowed\\\"],[[42192,42237],\\\"valid\\\"],[[42238,42239],\\\"valid\\\",[],\\\"NV8\\\"],[[42240,42508],\\\"valid\\\"],[[42509,42511],\\\"valid\\\",[],\\\"NV8\\\"],[[42512,42539],\\\"valid\\\"],[[42540,42559],\\\"disallowed\\\"],[[42560,42560],\\\"mapped\\\",[42561]],[[42561,42561],\\\"valid\\\"],[[42562,42562],\\\"mapped\\\",[42563]],[[42563,42563],\\\"valid\\\"],[[42564,42564],\\\"mapped\\\",[42565]],[[42565,42565],\\\"valid\\\"],[[42566,42566],\\\"mapped\\\",[42567]],[[42567,42567],\\\"valid\\\"],[[42568,42568],\\\"mapped\\\",[42569]],[[42569,42569],\\\"valid\\\"],[[42570,42570],\\\"mapped\\\",[42571]],[[42571,42571],\\\"valid\\\"],[[42572,42572],\\\"mapped\\\",[42573]],[[42573,42573],\\\"valid\\\"],[[42574,42574],\\\"mapped\\\",[42575]],[[42575,42575],\\\"valid\\\"],[[42576,42576],\\\"mapped\\\",[42577]],[[42577,42577],\\\"valid\\\"],[[42578,42578],\\\"mapped\\\",[42579]],[[42579,42579],\\\"valid\\\"],[[42580,42580],\\\"mapped\\\",[42581]],[[42581,42581],\\\"valid\\\"],[[42582,42582],\\\"mapped\\\",[42583]],[[42583,42583],\\\"valid\\\"],[[42584,42584],\\\"mapped\\\",[42585]],[[42585,42585],\\\"valid\\\"],[[42586,42586],\\\"mapped\\\",[42587]],[[42587,42587],\\\"valid\\\"],[[42588,42588],\\\"mapped\\\",[42589]],[[42589,42589],\\\"valid\\\"],[[42590,42590],\\\"mapped\\\",[42591]],[[42591,42591],\\\"valid\\\"],[[42592,42592],\\\"mapped\\\",[42593]],[[42593,42593],\\\"valid\\\"],[[42594,42594],\\\"mapped\\\",[42595]],[[42595,42595],\\\"valid\\\"],[[42596,42596],\\\"mapped\\\",[42597]],[[42597,42597],\\\"valid\\\"],[[42598,42598],\\\"mapped\\\",[42599]],[[42599,42599],\\\"valid\\\"],[[42600,42600],\\\"mapped\\\",[42601]],[[42601,42601],\\\"valid\\\"],[[42602,42602],\\\"mapped\\\",[42603]],[[42603,42603],\\\"valid\\\"],[[42604,42604],\\\"mapped\\\",[42605]],[[42605,42607],\\\"valid\\\"],[[42608,42611],\\\"valid\\\",[],\\\"NV8\\\"],[[42612,42619],\\\"valid\\\"],[[42620,42621],\\\"valid\\\"],[[42622,42622],\\\"valid\\\",[],\\\"NV8\\\"],[[42623,42623],\\\"valid\\\"],[[42624,42624],\\\"mapped\\\",[42625]],[[42625,42625],\\\"valid\\\"],[[42626,42626],\\\"mapped\\\",[42627]],[[42627,42627],\\\"valid\\\"],[[42628,42628],\\\"mapped\\\",[42629]],[[42629,42629],\\\"valid\\\"],[[42630,42630],\\\"mapped\\\",[42631]],[[42631,42631],\\\"valid\\\"],[[42632,42632],\\\"mapped\\\",[42633]],[[42633,42633],\\\"valid\\\"],[[42634,42634],\\\"mapped\\\",[42635]],[[42635,42635],\\\"valid\\\"],[[42636,42636],\\\"mapped\\\",[42637]],[[42637,42637],\\\"valid\\\"],[[42638,42638],\\\"mapped\\\",[42639]],[[42639,42639],\\\"valid\\\"],[[42640,42640],\\\"mapped\\\",[42641]],[[42641,42641],\\\"valid\\\"],[[42642,42642],\\\"mapped\\\",[42643]],[[42643,42643],\\\"valid\\\"],[[42644,42644],\\\"mapped\\\",[42645]],[[42645,42645],\\\"valid\\\"],[[42646,42646],\\\"mapped\\\",[42647]],[[42647,42647],\\\"valid\\\"],[[42648,42648],\\\"mapped\\\",[42649]],[[42649,42649],\\\"valid\\\"],[[42650,42650],\\\"mapped\\\",[42651]],[[42651,42651],\\\"valid\\\"],[[42652,42652],\\\"mapped\\\",[1098]],[[42653,42653],\\\"mapped\\\",[1100]],[[42654,42654],\\\"valid\\\"],[[42655,42655],\\\"valid\\\"],[[42656,42725],\\\"valid\\\"],[[42726,42735],\\\"valid\\\",[],\\\"NV8\\\"],[[42736,42737],\\\"valid\\\"],[[42738,42743],\\\"valid\\\",[],\\\"NV8\\\"],[[42744,42751],\\\"disallowed\\\"],[[42752,42774],\\\"valid\\\",[],\\\"NV8\\\"],[[42775,42778],\\\"valid\\\"],[[42779,42783],\\\"valid\\\"],[[42784,42785],\\\"valid\\\",[],\\\"NV8\\\"],[[42786,42786],\\\"mapped\\\",[42787]],[[42787,42787],\\\"valid\\\"],[[42788,42788],\\\"mapped\\\",[42789]],[[42789,42789],\\\"valid\\\"],[[42790,42790],\\\"mapped\\\",[42791]],[[42791,42791],\\\"valid\\\"],[[42792,42792],\\\"mapped\\\",[42793]],[[42793,42793],\\\"valid\\\"],[[42794,42794],\\\"mapped\\\",[42795]],[[42795,42795],\\\"valid\\\"],[[42796,42796],\\\"mapped\\\",[42797]],[[42797,42797],\\\"valid\\\"],[[42798,42798],\\\"mapped\\\",[42799]],[[42799,42801],\\\"valid\\\"],[[42802,42802],\\\"mapped\\\",[42803]],[[42803,42803],\\\"valid\\\"],[[42804,42804],\\\"mapped\\\",[42805]],[[42805,42805],\\\"valid\\\"],[[42806,42806],\\\"mapped\\\",[42807]],[[42807,42807],\\\"valid\\\"],[[42808,42808],\\\"mapped\\\",[42809]],[[42809,42809],\\\"valid\\\"],[[42810,42810],\\\"mapped\\\",[42811]],[[42811,42811],\\\"valid\\\"],[[42812,42812],\\\"mapped\\\",[42813]],[[42813,42813],\\\"valid\\\"],[[42814,42814],\\\"mapped\\\",[42815]],[[42815,42815],\\\"valid\\\"],[[42816,42816],\\\"mapped\\\",[42817]],[[42817,42817],\\\"valid\\\"],[[42818,42818],\\\"mapped\\\",[42819]],[[42819,42819],\\\"valid\\\"],[[42820,42820],\\\"mapped\\\",[42821]],[[42821,42821],\\\"valid\\\"],[[42822,42822],\\\"mapped\\\",[42823]],[[42823,42823],\\\"valid\\\"],[[42824,42824],\\\"mapped\\\",[42825]],[[42825,42825],\\\"valid\\\"],[[42826,42826],\\\"mapped\\\",[42827]],[[42827,42827],\\\"valid\\\"],[[42828,42828],\\\"mapped\\\",[42829]],[[42829,42829],\\\"valid\\\"],[[42830,42830],\\\"mapped\\\",[42831]],[[42831,42831],\\\"valid\\\"],[[42832,42832],\\\"mapped\\\",[42833]],[[42833,42833],\\\"valid\\\"],[[42834,42834],\\\"mapped\\\",[42835]],[[42835,42835],\\\"valid\\\"],[[42836,42836],\\\"mapped\\\",[42837]],[[42837,42837],\\\"valid\\\"],[[42838,42838],\\\"mapped\\\",[42839]],[[42839,42839],\\\"valid\\\"],[[42840,42840],\\\"mapped\\\",[42841]],[[42841,42841],\\\"valid\\\"],[[42842,42842],\\\"mapped\\\",[42843]],[[42843,42843],\\\"valid\\\"],[[42844,42844],\\\"mapped\\\",[42845]],[[42845,42845],\\\"valid\\\"],[[42846,42846],\\\"mapped\\\",[42847]],[[42847,42847],\\\"valid\\\"],[[42848,42848],\\\"mapped\\\",[42849]],[[42849,42849],\\\"valid\\\"],[[42850,42850],\\\"mapped\\\",[42851]],[[42851,42851],\\\"valid\\\"],[[42852,42852],\\\"mapped\\\",[42853]],[[42853,42853],\\\"valid\\\"],[[42854,42854],\\\"mapped\\\",[42855]],[[42855,42855],\\\"valid\\\"],[[42856,42856],\\\"mapped\\\",[42857]],[[42857,42857],\\\"valid\\\"],[[42858,42858],\\\"mapped\\\",[42859]],[[42859,42859],\\\"valid\\\"],[[42860,42860],\\\"mapped\\\",[42861]],[[42861,42861],\\\"valid\\\"],[[42862,42862],\\\"mapped\\\",[42863]],[[42863,42863],\\\"valid\\\"],[[42864,42864],\\\"mapped\\\",[42863]],[[42865,42872],\\\"valid\\\"],[[42873,42873],\\\"mapped\\\",[42874]],[[42874,42874],\\\"valid\\\"],[[42875,42875],\\\"mapped\\\",[42876]],[[42876,42876],\\\"valid\\\"],[[42877,42877],\\\"mapped\\\",[7545]],[[42878,42878],\\\"mapped\\\",[42879]],[[42879,42879],\\\"valid\\\"],[[42880,42880],\\\"mapped\\\",[42881]],[[42881,42881],\\\"valid\\\"],[[42882,42882],\\\"mapped\\\",[42883]],[[42883,42883],\\\"valid\\\"],[[42884,42884],\\\"mapped\\\",[42885]],[[42885,42885],\\\"valid\\\"],[[42886,42886],\\\"mapped\\\",[42887]],[[42887,42888],\\\"valid\\\"],[[42889,42890],\\\"valid\\\",[],\\\"NV8\\\"],[[42891,42891],\\\"mapped\\\",[42892]],[[42892,42892],\\\"valid\\\"],[[42893,42893],\\\"mapped\\\",[613]],[[42894,42894],\\\"valid\\\"],[[42895,42895],\\\"valid\\\"],[[42896,42896],\\\"mapped\\\",[42897]],[[42897,42897],\\\"valid\\\"],[[42898,42898],\\\"mapped\\\",[42899]],[[42899,42899],\\\"valid\\\"],[[42900,42901],\\\"valid\\\"],[[42902,42902],\\\"mapped\\\",[42903]],[[42903,42903],\\\"valid\\\"],[[42904,42904],\\\"mapped\\\",[42905]],[[42905,42905],\\\"valid\\\"],[[42906,42906],\\\"mapped\\\",[42907]],[[42907,42907],\\\"valid\\\"],[[42908,42908],\\\"mapped\\\",[42909]],[[42909,42909],\\\"valid\\\"],[[42910,42910],\\\"mapped\\\",[42911]],[[42911,42911],\\\"valid\\\"],[[42912,42912],\\\"mapped\\\",[42913]],[[42913,42913],\\\"valid\\\"],[[42914,42914],\\\"mapped\\\",[42915]],[[42915,42915],\\\"valid\\\"],[[42916,42916],\\\"mapped\\\",[42917]],[[42917,42917],\\\"valid\\\"],[[42918,42918],\\\"mapped\\\",[42919]],[[42919,42919],\\\"valid\\\"],[[42920,42920],\\\"mapped\\\",[42921]],[[42921,42921],\\\"valid\\\"],[[42922,42922],\\\"mapped\\\",[614]],[[42923,42923],\\\"mapped\\\",[604]],[[42924,42924],\\\"mapped\\\",[609]],[[42925,42925],\\\"mapped\\\",[620]],[[42926,42927],\\\"disallowed\\\"],[[42928,42928],\\\"mapped\\\",[670]],[[42929,42929],\\\"mapped\\\",[647]],[[42930,42930],\\\"mapped\\\",[669]],[[42931,42931],\\\"mapped\\\",[43859]],[[42932,42932],\\\"mapped\\\",[42933]],[[42933,42933],\\\"valid\\\"],[[42934,42934],\\\"mapped\\\",[42935]],[[42935,42935],\\\"valid\\\"],[[42936,42998],\\\"disallowed\\\"],[[42999,42999],\\\"valid\\\"],[[43000,43000],\\\"mapped\\\",[295]],[[43001,43001],\\\"mapped\\\",[339]],[[43002,43002],\\\"valid\\\"],[[43003,43007],\\\"valid\\\"],[[43008,43047],\\\"valid\\\"],[[43048,43051],\\\"valid\\\",[],\\\"NV8\\\"],[[43052,43055],\\\"disallowed\\\"],[[43056,43065],\\\"valid\\\",[],\\\"NV8\\\"],[[43066,43071],\\\"disallowed\\\"],[[43072,43123],\\\"valid\\\"],[[43124,43127],\\\"valid\\\",[],\\\"NV8\\\"],[[43128,43135],\\\"disallowed\\\"],[[43136,43204],\\\"valid\\\"],[[43205,43213],\\\"disallowed\\\"],[[43214,43215],\\\"valid\\\",[],\\\"NV8\\\"],[[43216,43225],\\\"valid\\\"],[[43226,43231],\\\"disallowed\\\"],[[43232,43255],\\\"valid\\\"],[[43256,43258],\\\"valid\\\",[],\\\"NV8\\\"],[[43259,43259],\\\"valid\\\"],[[43260,43260],\\\"valid\\\",[],\\\"NV8\\\"],[[43261,43261],\\\"valid\\\"],[[43262,43263],\\\"disallowed\\\"],[[43264,43309],\\\"valid\\\"],[[43310,43311],\\\"valid\\\",[],\\\"NV8\\\"],[[43312,43347],\\\"valid\\\"],[[43348,43358],\\\"disallowed\\\"],[[43359,43359],\\\"valid\\\",[],\\\"NV8\\\"],[[43360,43388],\\\"valid\\\",[],\\\"NV8\\\"],[[43389,43391],\\\"disallowed\\\"],[[43392,43456],\\\"valid\\\"],[[43457,43469],\\\"valid\\\",[],\\\"NV8\\\"],[[43470,43470],\\\"disallowed\\\"],[[43471,43481],\\\"valid\\\"],[[43482,43485],\\\"disallowed\\\"],[[43486,43487],\\\"valid\\\",[],\\\"NV8\\\"],[[43488,43518],\\\"valid\\\"],[[43519,43519],\\\"disallowed\\\"],[[43520,43574],\\\"valid\\\"],[[43575,43583],\\\"disallowed\\\"],[[43584,43597],\\\"valid\\\"],[[43598,43599],\\\"disallowed\\\"],[[43600,43609],\\\"valid\\\"],[[43610,43611],\\\"disallowed\\\"],[[43612,43615],\\\"valid\\\",[],\\\"NV8\\\"],[[43616,43638],\\\"valid\\\"],[[43639,43641],\\\"valid\\\",[],\\\"NV8\\\"],[[43642,43643],\\\"valid\\\"],[[43644,43647],\\\"valid\\\"],[[43648,43714],\\\"valid\\\"],[[43715,43738],\\\"disallowed\\\"],[[43739,43741],\\\"valid\\\"],[[43742,43743],\\\"valid\\\",[],\\\"NV8\\\"],[[43744,43759],\\\"valid\\\"],[[43760,43761],\\\"valid\\\",[],\\\"NV8\\\"],[[43762,43766],\\\"valid\\\"],[[43767,43776],\\\"disallowed\\\"],[[43777,43782],\\\"valid\\\"],[[43783,43784],\\\"disallowed\\\"],[[43785,43790],\\\"valid\\\"],[[43791,43792],\\\"disallowed\\\"],[[43793,43798],\\\"valid\\\"],[[43799,43807],\\\"disallowed\\\"],[[43808,43814],\\\"valid\\\"],[[43815,43815],\\\"disallowed\\\"],[[43816,43822],\\\"valid\\\"],[[43823,43823],\\\"disallowed\\\"],[[43824,43866],\\\"valid\\\"],[[43867,43867],\\\"valid\\\",[],\\\"NV8\\\"],[[43868,43868],\\\"mapped\\\",[42791]],[[43869,43869],\\\"mapped\\\",[43831]],[[43870,43870],\\\"mapped\\\",[619]],[[43871,43871],\\\"mapped\\\",[43858]],[[43872,43875],\\\"valid\\\"],[[43876,43877],\\\"valid\\\"],[[43878,43887],\\\"disallowed\\\"],[[43888,43888],\\\"mapped\\\",[5024]],[[43889,43889],\\\"mapped\\\",[5025]],[[43890,43890],\\\"mapped\\\",[5026]],[[43891,43891],\\\"mapped\\\",[5027]],[[43892,43892],\\\"mapped\\\",[5028]],[[43893,43893],\\\"mapped\\\",[5029]],[[43894,43894],\\\"mapped\\\",[5030]],[[43895,43895],\\\"mapped\\\",[5031]],[[43896,43896],\\\"mapped\\\",[5032]],[[43897,43897],\\\"mapped\\\",[5033]],[[43898,43898],\\\"mapped\\\",[5034]],[[43899,43899],\\\"mapped\\\",[5035]],[[43900,43900],\\\"mapped\\\",[5036]],[[43901,43901],\\\"mapped\\\",[5037]],[[43902,43902],\\\"mapped\\\",[5038]],[[43903,43903],\\\"mapped\\\",[5039]],[[43904,43904],\\\"mapped\\\",[5040]],[[43905,43905],\\\"mapped\\\",[5041]],[[43906,43906],\\\"mapped\\\",[5042]],[[43907,43907],\\\"mapped\\\",[5043]],[[43908,43908],\\\"mapped\\\",[5044]],[[43909,43909],\\\"mapped\\\",[5045]],[[43910,43910],\\\"mapped\\\",[5046]],[[43911,43911],\\\"mapped\\\",[5047]],[[43912,43912],\\\"mapped\\\",[5048]],[[43913,43913],\\\"mapped\\\",[5049]],[[43914,43914],\\\"mapped\\\",[5050]],[[43915,43915],\\\"mapped\\\",[5051]],[[43916,43916],\\\"mapped\\\",[5052]],[[43917,43917],\\\"mapped\\\",[5053]],[[43918,43918],\\\"mapped\\\",[5054]],[[43919,43919],\\\"mapped\\\",[5055]],[[43920,43920],\\\"mapped\\\",[5056]],[[43921,43921],\\\"mapped\\\",[5057]],[[43922,43922],\\\"mapped\\\",[5058]],[[43923,43923],\\\"mapped\\\",[5059]],[[43924,43924],\\\"mapped\\\",[5060]],[[43925,43925],\\\"mapped\\\",[5061]],[[43926,43926],\\\"mapped\\\",[5062]],[[43927,43927],\\\"mapped\\\",[5063]],[[43928,43928],\\\"mapped\\\",[5064]],[[43929,43929],\\\"mapped\\\",[5065]],[[43930,43930],\\\"mapped\\\",[5066]],[[43931,43931],\\\"mapped\\\",[5067]],[[43932,43932],\\\"mapped\\\",[5068]],[[43933,43933],\\\"mapped\\\",[5069]],[[43934,43934],\\\"mapped\\\",[5070]],[[43935,43935],\\\"mapped\\\",[5071]],[[43936,43936],\\\"mapped\\\",[5072]],[[43937,43937],\\\"mapped\\\",[5073]],[[43938,43938],\\\"mapped\\\",[5074]],[[43939,43939],\\\"mapped\\\",[5075]],[[43940,43940],\\\"mapped\\\",[5076]],[[43941,43941],\\\"mapped\\\",[5077]],[[43942,43942],\\\"mapped\\\",[5078]],[[43943,43943],\\\"mapped\\\",[5079]],[[43944,43944],\\\"mapped\\\",[5080]],[[43945,43945],\\\"mapped\\\",[5081]],[[43946,43946],\\\"mapped\\\",[5082]],[[43947,43947],\\\"mapped\\\",[5083]],[[43948,43948],\\\"mapped\\\",[5084]],[[43949,43949],\\\"mapped\\\",[5085]],[[43950,43950],\\\"mapped\\\",[5086]],[[43951,43951],\\\"mapped\\\",[5087]],[[43952,43952],\\\"mapped\\\",[5088]],[[43953,43953],\\\"mapped\\\",[5089]],[[43954,43954],\\\"mapped\\\",[5090]],[[43955,43955],\\\"mapped\\\",[5091]],[[43956,43956],\\\"mapped\\\",[5092]],[[43957,43957],\\\"mapped\\\",[5093]],[[43958,43958],\\\"mapped\\\",[5094]],[[43959,43959],\\\"mapped\\\",[5095]],[[43960,43960],\\\"mapped\\\",[5096]],[[43961,43961],\\\"mapped\\\",[5097]],[[43962,43962],\\\"mapped\\\",[5098]],[[43963,43963],\\\"mapped\\\",[5099]],[[43964,43964],\\\"mapped\\\",[5100]],[[43965,43965],\\\"mapped\\\",[5101]],[[43966,43966],\\\"mapped\\\",[5102]],[[43967,43967],\\\"mapped\\\",[5103]],[[43968,44010],\\\"valid\\\"],[[44011,44011],\\\"valid\\\",[],\\\"NV8\\\"],[[44012,44013],\\\"valid\\\"],[[44014,44015],\\\"disallowed\\\"],[[44016,44025],\\\"valid\\\"],[[44026,44031],\\\"disallowed\\\"],[[44032,55203],\\\"valid\\\"],[[55204,55215],\\\"disallowed\\\"],[[55216,55238],\\\"valid\\\",[],\\\"NV8\\\"],[[55239,55242],\\\"disallowed\\\"],[[55243,55291],\\\"valid\\\",[],\\\"NV8\\\"],[[55292,55295],\\\"disallowed\\\"],[[55296,57343],\\\"disallowed\\\"],[[57344,63743],\\\"disallowed\\\"],[[63744,63744],\\\"mapped\\\",[35912]],[[63745,63745],\\\"mapped\\\",[26356]],[[63746,63746],\\\"mapped\\\",[36554]],[[63747,63747],\\\"mapped\\\",[36040]],[[63748,63748],\\\"mapped\\\",[28369]],[[63749,63749],\\\"mapped\\\",[20018]],[[63750,63750],\\\"mapped\\\",[21477]],[[63751,63752],\\\"mapped\\\",[40860]],[[63753,63753],\\\"mapped\\\",[22865]],[[63754,63754],\\\"mapped\\\",[37329]],[[63755,63755],\\\"mapped\\\",[21895]],[[63756,63756],\\\"mapped\\\",[22856]],[[63757,63757],\\\"mapped\\\",[25078]],[[63758,63758],\\\"mapped\\\",[30313]],[[63759,63759],\\\"mapped\\\",[32645]],[[63760,63760],\\\"mapped\\\",[34367]],[[63761,63761],\\\"mapped\\\",[34746]],[[63762,63762],\\\"mapped\\\",[35064]],[[63763,63763],\\\"mapped\\\",[37007]],[[63764,63764],\\\"mapped\\\",[27138]],[[63765,63765],\\\"mapped\\\",[27931]],[[63766,63766],\\\"mapped\\\",[28889]],[[63767,63767],\\\"mapped\\\",[29662]],[[63768,63768],\\\"mapped\\\",[33853]],[[63769,63769],\\\"mapped\\\",[37226]],[[63770,63770],\\\"mapped\\\",[39409]],[[63771,63771],\\\"mapped\\\",[20098]],[[63772,63772],\\\"mapped\\\",[21365]],[[63773,63773],\\\"mapped\\\",[27396]],[[63774,63774],\\\"mapped\\\",[29211]],[[63775,63775],\\\"mapped\\\",[34349]],[[63776,63776],\\\"mapped\\\",[40478]],[[63777,63777],\\\"mapped\\\",[23888]],[[63778,63778],\\\"mapped\\\",[28651]],[[63779,63779],\\\"mapped\\\",[34253]],[[63780,63780],\\\"mapped\\\",[35172]],[[63781,63781],\\\"mapped\\\",[25289]],[[63782,63782],\\\"mapped\\\",[33240]],[[63783,63783],\\\"mapped\\\",[34847]],[[63784,63784],\\\"mapped\\\",[24266]],[[63785,63785],\\\"mapped\\\",[26391]],[[63786,63786],\\\"mapped\\\",[28010]],[[63787,63787],\\\"mapped\\\",[29436]],[[63788,63788],\\\"mapped\\\",[37070]],[[63789,63789],\\\"mapped\\\",[20358]],[[63790,63790],\\\"mapped\\\",[20919]],[[63791,63791],\\\"mapped\\\",[21214]],[[63792,63792],\\\"mapped\\\",[25796]],[[63793,63793],\\\"mapped\\\",[27347]],[[63794,63794],\\\"mapped\\\",[29200]],[[63795,63795],\\\"mapped\\\",[30439]],[[63796,63796],\\\"mapped\\\",[32769]],[[63797,63797],\\\"mapped\\\",[34310]],[[63798,63798],\\\"mapped\\\",[34396]],[[63799,63799],\\\"mapped\\\",[36335]],[[63800,63800],\\\"mapped\\\",[38706]],[[63801,63801],\\\"mapped\\\",[39791]],[[63802,63802],\\\"mapped\\\",[40442]],[[63803,63803],\\\"mapped\\\",[30860]],[[63804,63804],\\\"mapped\\\",[31103]],[[63805,63805],\\\"mapped\\\",[32160]],[[63806,63806],\\\"mapped\\\",[33737]],[[63807,63807],\\\"mapped\\\",[37636]],[[63808,63808],\\\"mapped\\\",[40575]],[[63809,63809],\\\"mapped\\\",[35542]],[[63810,63810],\\\"mapped\\\",[22751]],[[63811,63811],\\\"mapped\\\",[24324]],[[63812,63812],\\\"mapped\\\",[31840]],[[63813,63813],\\\"mapped\\\",[32894]],[[63814,63814],\\\"mapped\\\",[29282]],[[63815,63815],\\\"mapped\\\",[30922]],[[63816,63816],\\\"mapped\\\",[36034]],[[63817,63817],\\\"mapped\\\",[38647]],[[63818,63818],\\\"mapped\\\",[22744]],[[63819,63819],\\\"mapped\\\",[23650]],[[63820,63820],\\\"mapped\\\",[27155]],[[63821,63821],\\\"mapped\\\",[28122]],[[63822,63822],\\\"mapped\\\",[28431]],[[63823,63823],\\\"mapped\\\",[32047]],[[63824,63824],\\\"mapped\\\",[32311]],[[63825,63825],\\\"mapped\\\",[38475]],[[63826,63826],\\\"mapped\\\",[21202]],[[63827,63827],\\\"mapped\\\",[32907]],[[63828,63828],\\\"mapped\\\",[20956]],[[63829,63829],\\\"mapped\\\",[20940]],[[63830,63830],\\\"mapped\\\",[31260]],[[63831,63831],\\\"mapped\\\",[32190]],[[63832,63832],\\\"mapped\\\",[33777]],[[63833,63833],\\\"mapped\\\",[38517]],[[63834,63834],\\\"mapped\\\",[35712]],[[63835,63835],\\\"mapped\\\",[25295]],[[63836,63836],\\\"mapped\\\",[27138]],[[63837,63837],\\\"mapped\\\",[35582]],[[63838,63838],\\\"mapped\\\",[20025]],[[63839,63839],\\\"mapped\\\",[23527]],[[63840,63840],\\\"mapped\\\",[24594]],[[63841,63841],\\\"mapped\\\",[29575]],[[63842,63842],\\\"mapped\\\",[30064]],[[63843,63843],\\\"mapped\\\",[21271]],[[63844,63844],\\\"mapped\\\",[30971]],[[63845,63845],\\\"mapped\\\",[20415]],[[63846,63846],\\\"mapped\\\",[24489]],[[63847,63847],\\\"mapped\\\",[19981]],[[63848,63848],\\\"mapped\\\",[27852]],[[63849,63849],\\\"mapped\\\",[25976]],[[63850,63850],\\\"mapped\\\",[32034]],[[63851,63851],\\\"mapped\\\",[21443]],[[63852,63852],\\\"mapped\\\",[22622]],[[63853,63853],\\\"mapped\\\",[30465]],[[63854,63854],\\\"mapped\\\",[33865]],[[63855,63855],\\\"mapped\\\",[35498]],[[63856,63856],\\\"mapped\\\",[27578]],[[63857,63857],\\\"mapped\\\",[36784]],[[63858,63858],\\\"mapped\\\",[27784]],[[63859,63859],\\\"mapped\\\",[25342]],[[63860,63860],\\\"mapped\\\",[33509]],[[63861,63861],\\\"mapped\\\",[25504]],[[63862,63862],\\\"mapped\\\",[30053]],[[63863,63863],\\\"mapped\\\",[20142]],[[63864,63864],\\\"mapped\\\",[20841]],[[63865,63865],\\\"mapped\\\",[20937]],[[63866,63866],\\\"mapped\\\",[26753]],[[63867,63867],\\\"mapped\\\",[31975]],[[63868,63868],\\\"mapped\\\",[33391]],[[63869,63869],\\\"mapped\\\",[35538]],[[63870,63870],\\\"mapped\\\",[37327]],[[63871,63871],\\\"mapped\\\",[21237]],[[63872,63872],\\\"mapped\\\",[21570]],[[63873,63873],\\\"mapped\\\",[22899]],[[63874,63874],\\\"mapped\\\",[24300]],[[63875,63875],\\\"mapped\\\",[26053]],[[63876,63876],\\\"mapped\\\",[28670]],[[63877,63877],\\\"mapped\\\",[31018]],[[63878,63878],\\\"mapped\\\",[38317]],[[63879,63879],\\\"mapped\\\",[39530]],[[63880,63880],\\\"mapped\\\",[40599]],[[63881,63881],\\\"mapped\\\",[40654]],[[63882,63882],\\\"mapped\\\",[21147]],[[63883,63883],\\\"mapped\\\",[26310]],[[63884,63884],\\\"mapped\\\",[27511]],[[63885,63885],\\\"mapped\\\",[36706]],[[63886,63886],\\\"mapped\\\",[24180]],[[63887,63887],\\\"mapped\\\",[24976]],[[63888,63888],\\\"mapped\\\",[25088]],[[63889,63889],\\\"mapped\\\",[25754]],[[63890,63890],\\\"mapped\\\",[28451]],[[63891,63891],\\\"mapped\\\",[29001]],[[63892,63892],\\\"mapped\\\",[29833]],[[63893,63893],\\\"mapped\\\",[31178]],[[63894,63894],\\\"mapped\\\",[32244]],[[63895,63895],\\\"mapped\\\",[32879]],[[63896,63896],\\\"mapped\\\",[36646]],[[63897,63897],\\\"mapped\\\",[34030]],[[63898,63898],\\\"mapped\\\",[36899]],[[63899,63899],\\\"mapped\\\",[37706]],[[63900,63900],\\\"mapped\\\",[21015]],[[63901,63901],\\\"mapped\\\",[21155]],[[63902,63902],\\\"mapped\\\",[21693]],[[63903,63903],\\\"mapped\\\",[28872]],[[63904,63904],\\\"mapped\\\",[35010]],[[63905,63905],\\\"mapped\\\",[35498]],[[63906,63906],\\\"mapped\\\",[24265]],[[63907,63907],\\\"mapped\\\",[24565]],[[63908,63908],\\\"mapped\\\",[25467]],[[63909,63909],\\\"mapped\\\",[27566]],[[63910,63910],\\\"mapped\\\",[31806]],[[63911,63911],\\\"mapped\\\",[29557]],[[63912,63912],\\\"mapped\\\",[20196]],[[63913,63913],\\\"mapped\\\",[22265]],[[63914,63914],\\\"mapped\\\",[23527]],[[63915,63915],\\\"mapped\\\",[23994]],[[63916,63916],\\\"mapped\\\",[24604]],[[63917,63917],\\\"mapped\\\",[29618]],[[63918,63918],\\\"mapped\\\",[29801]],[[63919,63919],\\\"mapped\\\",[32666]],[[63920,63920],\\\"mapped\\\",[32838]],[[63921,63921],\\\"mapped\\\",[37428]],[[63922,63922],\\\"mapped\\\",[38646]],[[63923,63923],\\\"mapped\\\",[38728]],[[63924,63924],\\\"mapped\\\",[38936]],[[63925,63925],\\\"mapped\\\",[20363]],[[63926,63926],\\\"mapped\\\",[31150]],[[63927,63927],\\\"mapped\\\",[37300]],[[63928,63928],\\\"mapped\\\",[38584]],[[63929,63929],\\\"mapped\\\",[24801]],[[63930,63930],\\\"mapped\\\",[20102]],[[63931,63931],\\\"mapped\\\",[20698]],[[63932,63932],\\\"mapped\\\",[23534]],[[63933,63933],\\\"mapped\\\",[23615]],[[63934,63934],\\\"mapped\\\",[26009]],[[63935,63935],\\\"mapped\\\",[27138]],[[63936,63936],\\\"mapped\\\",[29134]],[[63937,63937],\\\"mapped\\\",[30274]],[[63938,63938],\\\"mapped\\\",[34044]],[[63939,63939],\\\"mapped\\\",[36988]],[[63940,63940],\\\"mapped\\\",[40845]],[[63941,63941],\\\"mapped\\\",[26248]],[[63942,63942],\\\"mapped\\\",[38446]],[[63943,63943],\\\"mapped\\\",[21129]],[[63944,63944],\\\"mapped\\\",[26491]],[[63945,63945],\\\"mapped\\\",[26611]],[[63946,63946],\\\"mapped\\\",[27969]],[[63947,63947],\\\"mapped\\\",[28316]],[[63948,63948],\\\"mapped\\\",[29705]],[[63949,63949],\\\"mapped\\\",[30041]],[[63950,63950],\\\"mapped\\\",[30827]],[[63951,63951],\\\"mapped\\\",[32016]],[[63952,63952],\\\"mapped\\\",[39006]],[[63953,63953],\\\"mapped\\\",[20845]],[[63954,63954],\\\"mapped\\\",[25134]],[[63955,63955],\\\"mapped\\\",[38520]],[[63956,63956],\\\"mapped\\\",[20523]],[[63957,63957],\\\"mapped\\\",[23833]],[[63958,63958],\\\"mapped\\\",[28138]],[[63959,63959],\\\"mapped\\\",[36650]],[[63960,63960],\\\"mapped\\\",[24459]],[[63961,63961],\\\"mapped\\\",[24900]],[[63962,63962],\\\"mapped\\\",[26647]],[[63963,63963],\\\"mapped\\\",[29575]],[[63964,63964],\\\"mapped\\\",[38534]],[[63965,63965],\\\"mapped\\\",[21033]],[[63966,63966],\\\"mapped\\\",[21519]],[[63967,63967],\\\"mapped\\\",[23653]],[[63968,63968],\\\"mapped\\\",[26131]],[[63969,63969],\\\"mapped\\\",[26446]],[[63970,63970],\\\"mapped\\\",[26792]],[[63971,63971],\\\"mapped\\\",[27877]],[[63972,63972],\\\"mapped\\\",[29702]],[[63973,63973],\\\"mapped\\\",[30178]],[[63974,63974],\\\"mapped\\\",[32633]],[[63975,63975],\\\"mapped\\\",[35023]],[[63976,63976],\\\"mapped\\\",[35041]],[[63977,63977],\\\"mapped\\\",[37324]],[[63978,63978],\\\"mapped\\\",[38626]],[[63979,63979],\\\"mapped\\\",[21311]],[[63980,63980],\\\"mapped\\\",[28346]],[[63981,63981],\\\"mapped\\\",[21533]],[[63982,63982],\\\"mapped\\\",[29136]],[[63983,63983],\\\"mapped\\\",[29848]],[[63984,63984],\\\"mapped\\\",[34298]],[[63985,63985],\\\"mapped\\\",[38563]],[[63986,63986],\\\"mapped\\\",[40023]],[[63987,63987],\\\"mapped\\\",[40607]],[[63988,63988],\\\"mapped\\\",[26519]],[[63989,63989],\\\"mapped\\\",[28107]],[[63990,63990],\\\"mapped\\\",[33256]],[[63991,63991],\\\"mapped\\\",[31435]],[[63992,63992],\\\"mapped\\\",[31520]],[[63993,63993],\\\"mapped\\\",[31890]],[[63994,63994],\\\"mapped\\\",[29376]],[[63995,63995],\\\"mapped\\\",[28825]],[[63996,63996],\\\"mapped\\\",[35672]],[[63997,63997],\\\"mapped\\\",[20160]],[[63998,63998],\\\"mapped\\\",[33590]],[[63999,63999],\\\"mapped\\\",[21050]],[[64000,64000],\\\"mapped\\\",[20999]],[[64001,64001],\\\"mapped\\\",[24230]],[[64002,64002],\\\"mapped\\\",[25299]],[[64003,64003],\\\"mapped\\\",[31958]],[[64004,64004],\\\"mapped\\\",[23429]],[[64005,64005],\\\"mapped\\\",[27934]],[[64006,64006],\\\"mapped\\\",[26292]],[[64007,64007],\\\"mapped\\\",[36667]],[[64008,64008],\\\"mapped\\\",[34892]],[[64009,64009],\\\"mapped\\\",[38477]],[[64010,64010],\\\"mapped\\\",[35211]],[[64011,64011],\\\"mapped\\\",[24275]],[[64012,64012],\\\"mapped\\\",[20800]],[[64013,64013],\\\"mapped\\\",[21952]],[[64014,64015],\\\"valid\\\"],[[64016,64016],\\\"mapped\\\",[22618]],[[64017,64017],\\\"valid\\\"],[[64018,64018],\\\"mapped\\\",[26228]],[[64019,64020],\\\"valid\\\"],[[64021,64021],\\\"mapped\\\",[20958]],[[64022,64022],\\\"mapped\\\",[29482]],[[64023,64023],\\\"mapped\\\",[30410]],[[64024,64024],\\\"mapped\\\",[31036]],[[64025,64025],\\\"mapped\\\",[31070]],[[64026,64026],\\\"mapped\\\",[31077]],[[64027,64027],\\\"mapped\\\",[31119]],[[64028,64028],\\\"mapped\\\",[38742]],[[64029,64029],\\\"mapped\\\",[31934]],[[64030,64030],\\\"mapped\\\",[32701]],[[64031,64031],\\\"valid\\\"],[[64032,64032],\\\"mapped\\\",[34322]],[[64033,64033],\\\"valid\\\"],[[64034,64034],\\\"mapped\\\",[35576]],[[64035,64036],\\\"valid\\\"],[[64037,64037],\\\"mapped\\\",[36920]],[[64038,64038],\\\"mapped\\\",[37117]],[[64039,64041],\\\"valid\\\"],[[64042,64042],\\\"mapped\\\",[39151]],[[64043,64043],\\\"mapped\\\",[39164]],[[64044,64044],\\\"mapped\\\",[39208]],[[64045,64045],\\\"mapped\\\",[40372]],[[64046,64046],\\\"mapped\\\",[37086]],[[64047,64047],\\\"mapped\\\",[38583]],[[64048,64048],\\\"mapped\\\",[20398]],[[64049,64049],\\\"mapped\\\",[20711]],[[64050,64050],\\\"mapped\\\",[20813]],[[64051,64051],\\\"mapped\\\",[21193]],[[64052,64052],\\\"mapped\\\",[21220]],[[64053,64053],\\\"mapped\\\",[21329]],[[64054,64054],\\\"mapped\\\",[21917]],[[64055,64055],\\\"mapped\\\",[22022]],[[64056,64056],\\\"mapped\\\",[22120]],[[64057,64057],\\\"mapped\\\",[22592]],[[64058,64058],\\\"mapped\\\",[22696]],[[64059,64059],\\\"mapped\\\",[23652]],[[64060,64060],\\\"mapped\\\",[23662]],[[64061,64061],\\\"mapped\\\",[24724]],[[64062,64062],\\\"mapped\\\",[24936]],[[64063,64063],\\\"mapped\\\",[24974]],[[64064,64064],\\\"mapped\\\",[25074]],[[64065,64065],\\\"mapped\\\",[25935]],[[64066,64066],\\\"mapped\\\",[26082]],[[64067,64067],\\\"mapped\\\",[26257]],[[64068,64068],\\\"mapped\\\",[26757]],[[64069,64069],\\\"mapped\\\",[28023]],[[64070,64070],\\\"mapped\\\",[28186]],[[64071,64071],\\\"mapped\\\",[28450]],[[64072,64072],\\\"mapped\\\",[29038]],[[64073,64073],\\\"mapped\\\",[29227]],[[64074,64074],\\\"mapped\\\",[29730]],[[64075,64075],\\\"mapped\\\",[30865]],[[64076,64076],\\\"mapped\\\",[31038]],[[64077,64077],\\\"mapped\\\",[31049]],[[64078,64078],\\\"mapped\\\",[31048]],[[64079,64079],\\\"mapped\\\",[31056]],[[64080,64080],\\\"mapped\\\",[31062]],[[64081,64081],\\\"mapped\\\",[31069]],[[64082,64082],\\\"mapped\\\",[31117]],[[64083,64083],\\\"mapped\\\",[31118]],[[64084,64084],\\\"mapped\\\",[31296]],[[64085,64085],\\\"mapped\\\",[31361]],[[64086,64086],\\\"mapped\\\",[31680]],[[64087,64087],\\\"mapped\\\",[32244]],[[64088,64088],\\\"mapped\\\",[32265]],[[64089,64089],\\\"mapped\\\",[32321]],[[64090,64090],\\\"mapped\\\",[32626]],[[64091,64091],\\\"mapped\\\",[32773]],[[64092,64092],\\\"mapped\\\",[33261]],[[64093,64094],\\\"mapped\\\",[33401]],[[64095,64095],\\\"mapped\\\",[33879]],[[64096,64096],\\\"mapped\\\",[35088]],[[64097,64097],\\\"mapped\\\",[35222]],[[64098,64098],\\\"mapped\\\",[35585]],[[64099,64099],\\\"mapped\\\",[35641]],[[64100,64100],\\\"mapped\\\",[36051]],[[64101,64101],\\\"mapped\\\",[36104]],[[64102,64102],\\\"mapped\\\",[36790]],[[64103,64103],\\\"mapped\\\",[36920]],[[64104,64104],\\\"mapped\\\",[38627]],[[64105,64105],\\\"mapped\\\",[38911]],[[64106,64106],\\\"mapped\\\",[38971]],[[64107,64107],\\\"mapped\\\",[24693]],[[64108,64108],\\\"mapped\\\",[148206]],[[64109,64109],\\\"mapped\\\",[33304]],[[64110,64111],\\\"disallowed\\\"],[[64112,64112],\\\"mapped\\\",[20006]],[[64113,64113],\\\"mapped\\\",[20917]],[[64114,64114],\\\"mapped\\\",[20840]],[[64115,64115],\\\"mapped\\\",[20352]],[[64116,64116],\\\"mapped\\\",[20805]],[[64117,64117],\\\"mapped\\\",[20864]],[[64118,64118],\\\"mapped\\\",[21191]],[[64119,64119],\\\"mapped\\\",[21242]],[[64120,64120],\\\"mapped\\\",[21917]],[[64121,64121],\\\"mapped\\\",[21845]],[[64122,64122],\\\"mapped\\\",[21913]],[[64123,64123],\\\"mapped\\\",[21986]],[[64124,64124],\\\"mapped\\\",[22618]],[[64125,64125],\\\"mapped\\\",[22707]],[[64126,64126],\\\"mapped\\\",[22852]],[[64127,64127],\\\"mapped\\\",[22868]],[[64128,64128],\\\"mapped\\\",[23138]],[[64129,64129],\\\"mapped\\\",[23336]],[[64130,64130],\\\"mapped\\\",[24274]],[[64131,64131],\\\"mapped\\\",[24281]],[[64132,64132],\\\"mapped\\\",[24425]],[[64133,64133],\\\"mapped\\\",[24493]],[[64134,64134],\\\"mapped\\\",[24792]],[[64135,64135],\\\"mapped\\\",[24910]],[[64136,64136],\\\"mapped\\\",[24840]],[[64137,64137],\\\"mapped\\\",[24974]],[[64138,64138],\\\"mapped\\\",[24928]],[[64139,64139],\\\"mapped\\\",[25074]],[[64140,64140],\\\"mapped\\\",[25140]],[[64141,64141],\\\"mapped\\\",[25540]],[[64142,64142],\\\"mapped\\\",[25628]],[[64143,64143],\\\"mapped\\\",[25682]],[[64144,64144],\\\"mapped\\\",[25942]],[[64145,64145],\\\"mapped\\\",[26228]],[[64146,64146],\\\"mapped\\\",[26391]],[[64147,64147],\\\"mapped\\\",[26395]],[[64148,64148],\\\"mapped\\\",[26454]],[[64149,64149],\\\"mapped\\\",[27513]],[[64150,64150],\\\"mapped\\\",[27578]],[[64151,64151],\\\"mapped\\\",[27969]],[[64152,64152],\\\"mapped\\\",[28379]],[[64153,64153],\\\"mapped\\\",[28363]],[[64154,64154],\\\"mapped\\\",[28450]],[[64155,64155],\\\"mapped\\\",[28702]],[[64156,64156],\\\"mapped\\\",[29038]],[[64157,64157],\\\"mapped\\\",[30631]],[[64158,64158],\\\"mapped\\\",[29237]],[[64159,64159],\\\"mapped\\\",[29359]],[[64160,64160],\\\"mapped\\\",[29482]],[[64161,64161],\\\"mapped\\\",[29809]],[[64162,64162],\\\"mapped\\\",[29958]],[[64163,64163],\\\"mapped\\\",[30011]],[[64164,64164],\\\"mapped\\\",[30237]],[[64165,64165],\\\"mapped\\\",[30239]],[[64166,64166],\\\"mapped\\\",[30410]],[[64167,64167],\\\"mapped\\\",[30427]],[[64168,64168],\\\"mapped\\\",[30452]],[[64169,64169],\\\"mapped\\\",[30538]],[[64170,64170],\\\"mapped\\\",[30528]],[[64171,64171],\\\"mapped\\\",[30924]],[[64172,64172],\\\"mapped\\\",[31409]],[[64173,64173],\\\"mapped\\\",[31680]],[[64174,64174],\\\"mapped\\\",[31867]],[[64175,64175],\\\"mapped\\\",[32091]],[[64176,64176],\\\"mapped\\\",[32244]],[[64177,64177],\\\"mapped\\\",[32574]],[[64178,64178],\\\"mapped\\\",[32773]],[[64179,64179],\\\"mapped\\\",[33618]],[[64180,64180],\\\"mapped\\\",[33775]],[[64181,64181],\\\"mapped\\\",[34681]],[[64182,64182],\\\"mapped\\\",[35137]],[[64183,64183],\\\"mapped\\\",[35206]],[[64184,64184],\\\"mapped\\\",[35222]],[[64185,64185],\\\"mapped\\\",[35519]],[[64186,64186],\\\"mapped\\\",[35576]],[[64187,64187],\\\"mapped\\\",[35531]],[[64188,64188],\\\"mapped\\\",[35585]],[[64189,64189],\\\"mapped\\\",[35582]],[[64190,64190],\\\"mapped\\\",[35565]],[[64191,64191],\\\"mapped\\\",[35641]],[[64192,64192],\\\"mapped\\\",[35722]],[[64193,64193],\\\"mapped\\\",[36104]],[[64194,64194],\\\"mapped\\\",[36664]],[[64195,64195],\\\"mapped\\\",[36978]],[[64196,64196],\\\"mapped\\\",[37273]],[[64197,64197],\\\"mapped\\\",[37494]],[[64198,64198],\\\"mapped\\\",[38524]],[[64199,64199],\\\"mapped\\\",[38627]],[[64200,64200],\\\"mapped\\\",[38742]],[[64201,64201],\\\"mapped\\\",[38875]],[[64202,64202],\\\"mapped\\\",[38911]],[[64203,64203],\\\"mapped\\\",[38923]],[[64204,64204],\\\"mapped\\\",[38971]],[[64205,64205],\\\"mapped\\\",[39698]],[[64206,64206],\\\"mapped\\\",[40860]],[[64207,64207],\\\"mapped\\\",[141386]],[[64208,64208],\\\"mapped\\\",[141380]],[[64209,64209],\\\"mapped\\\",[144341]],[[64210,64210],\\\"mapped\\\",[15261]],[[64211,64211],\\\"mapped\\\",[16408]],[[64212,64212],\\\"mapped\\\",[16441]],[[64213,64213],\\\"mapped\\\",[152137]],[[64214,64214],\\\"mapped\\\",[154832]],[[64215,64215],\\\"mapped\\\",[163539]],[[64216,64216],\\\"mapped\\\",[40771]],[[64217,64217],\\\"mapped\\\",[40846]],[[64218,64255],\\\"disallowed\\\"],[[64256,64256],\\\"mapped\\\",[102,102]],[[64257,64257],\\\"mapped\\\",[102,105]],[[64258,64258],\\\"mapped\\\",[102,108]],[[64259,64259],\\\"mapped\\\",[102,102,105]],[[64260,64260],\\\"mapped\\\",[102,102,108]],[[64261,64262],\\\"mapped\\\",[115,116]],[[64263,64274],\\\"disallowed\\\"],[[64275,64275],\\\"mapped\\\",[1396,1398]],[[64276,64276],\\\"mapped\\\",[1396,1381]],[[64277,64277],\\\"mapped\\\",[1396,1387]],[[64278,64278],\\\"mapped\\\",[1406,1398]],[[64279,64279],\\\"mapped\\\",[1396,1389]],[[64280,64284],\\\"disallowed\\\"],[[64285,64285],\\\"mapped\\\",[1497,1460]],[[64286,64286],\\\"valid\\\"],[[64287,64287],\\\"mapped\\\",[1522,1463]],[[64288,64288],\\\"mapped\\\",[1506]],[[64289,64289],\\\"mapped\\\",[1488]],[[64290,64290],\\\"mapped\\\",[1491]],[[64291,64291],\\\"mapped\\\",[1492]],[[64292,64292],\\\"mapped\\\",[1499]],[[64293,64293],\\\"mapped\\\",[1500]],[[64294,64294],\\\"mapped\\\",[1501]],[[64295,64295],\\\"mapped\\\",[1512]],[[64296,64296],\\\"mapped\\\",[1514]],[[64297,64297],\\\"disallowed_STD3_mapped\\\",[43]],[[64298,64298],\\\"mapped\\\",[1513,1473]],[[64299,64299],\\\"mapped\\\",[1513,1474]],[[64300,64300],\\\"mapped\\\",[1513,1468,1473]],[[64301,64301],\\\"mapped\\\",[1513,1468,1474]],[[64302,64302],\\\"mapped\\\",[1488,1463]],[[64303,64303],\\\"mapped\\\",[1488,1464]],[[64304,64304],\\\"mapped\\\",[1488,1468]],[[64305,64305],\\\"mapped\\\",[1489,1468]],[[64306,64306],\\\"mapped\\\",[1490,1468]],[[64307,64307],\\\"mapped\\\",[1491,1468]],[[64308,64308],\\\"mapped\\\",[1492,1468]],[[64309,64309],\\\"mapped\\\",[1493,1468]],[[64310,64310],\\\"mapped\\\",[1494,1468]],[[64311,64311],\\\"disallowed\\\"],[[64312,64312],\\\"mapped\\\",[1496,1468]],[[64313,64313],\\\"mapped\\\",[1497,1468]],[[64314,64314],\\\"mapped\\\",[1498,1468]],[[64315,64315],\\\"mapped\\\",[1499,1468]],[[64316,64316],\\\"mapped\\\",[1500,1468]],[[64317,64317],\\\"disallowed\\\"],[[64318,64318],\\\"mapped\\\",[1502,1468]],[[64319,64319],\\\"disallowed\\\"],[[64320,64320],\\\"mapped\\\",[1504,1468]],[[64321,64321],\\\"mapped\\\",[1505,1468]],[[64322,64322],\\\"disallowed\\\"],[[64323,64323],\\\"mapped\\\",[1507,1468]],[[64324,64324],\\\"mapped\\\",[1508,1468]],[[64325,64325],\\\"disallowed\\\"],[[64326,64326],\\\"mapped\\\",[1510,1468]],[[64327,64327],\\\"mapped\\\",[1511,1468]],[[64328,64328],\\\"mapped\\\",[1512,1468]],[[64329,64329],\\\"mapped\\\",[1513,1468]],[[64330,64330],\\\"mapped\\\",[1514,1468]],[[64331,64331],\\\"mapped\\\",[1493,1465]],[[64332,64332],\\\"mapped\\\",[1489,1471]],[[64333,64333],\\\"mapped\\\",[1499,1471]],[[64334,64334],\\\"mapped\\\",[1508,1471]],[[64335,64335],\\\"mapped\\\",[1488,1500]],[[64336,64337],\\\"mapped\\\",[1649]],[[64338,64341],\\\"mapped\\\",[1659]],[[64342,64345],\\\"mapped\\\",[1662]],[[64346,64349],\\\"mapped\\\",[1664]],[[64350,64353],\\\"mapped\\\",[1658]],[[64354,64357],\\\"mapped\\\",[1663]],[[64358,64361],\\\"mapped\\\",[1657]],[[64362,64365],\\\"mapped\\\",[1700]],[[64366,64369],\\\"mapped\\\",[1702]],[[64370,64373],\\\"mapped\\\",[1668]],[[64374,64377],\\\"mapped\\\",[1667]],[[64378,64381],\\\"mapped\\\",[1670]],[[64382,64385],\\\"mapped\\\",[1671]],[[64386,64387],\\\"mapped\\\",[1677]],[[64388,64389],\\\"mapped\\\",[1676]],[[64390,64391],\\\"mapped\\\",[1678]],[[64392,64393],\\\"mapped\\\",[1672]],[[64394,64395],\\\"mapped\\\",[1688]],[[64396,64397],\\\"mapped\\\",[1681]],[[64398,64401],\\\"mapped\\\",[1705]],[[64402,64405],\\\"mapped\\\",[1711]],[[64406,64409],\\\"mapped\\\",[1715]],[[64410,64413],\\\"mapped\\\",[1713]],[[64414,64415],\\\"mapped\\\",[1722]],[[64416,64419],\\\"mapped\\\",[1723]],[[64420,64421],\\\"mapped\\\",[1728]],[[64422,64425],\\\"mapped\\\",[1729]],[[64426,64429],\\\"mapped\\\",[1726]],[[64430,64431],\\\"mapped\\\",[1746]],[[64432,64433],\\\"mapped\\\",[1747]],[[64434,64449],\\\"valid\\\",[],\\\"NV8\\\"],[[64450,64466],\\\"disallowed\\\"],[[64467,64470],\\\"mapped\\\",[1709]],[[64471,64472],\\\"mapped\\\",[1735]],[[64473,64474],\\\"mapped\\\",[1734]],[[64475,64476],\\\"mapped\\\",[1736]],[[64477,64477],\\\"mapped\\\",[1735,1652]],[[64478,64479],\\\"mapped\\\",[1739]],[[64480,64481],\\\"mapped\\\",[1733]],[[64482,64483],\\\"mapped\\\",[1737]],[[64484,64487],\\\"mapped\\\",[1744]],[[64488,64489],\\\"mapped\\\",[1609]],[[64490,64491],\\\"mapped\\\",[1574,1575]],[[64492,64493],\\\"mapped\\\",[1574,1749]],[[64494,64495],\\\"mapped\\\",[1574,1608]],[[64496,64497],\\\"mapped\\\",[1574,1735]],[[64498,64499],\\\"mapped\\\",[1574,1734]],[[64500,64501],\\\"mapped\\\",[1574,1736]],[[64502,64504],\\\"mapped\\\",[1574,1744]],[[64505,64507],\\\"mapped\\\",[1574,1609]],[[64508,64511],\\\"mapped\\\",[1740]],[[64512,64512],\\\"mapped\\\",[1574,1580]],[[64513,64513],\\\"mapped\\\",[1574,1581]],[[64514,64514],\\\"mapped\\\",[1574,1605]],[[64515,64515],\\\"mapped\\\",[1574,1609]],[[64516,64516],\\\"mapped\\\",[1574,1610]],[[64517,64517],\\\"mapped\\\",[1576,1580]],[[64518,64518],\\\"mapped\\\",[1576,1581]],[[64519,64519],\\\"mapped\\\",[1576,1582]],[[64520,64520],\\\"mapped\\\",[1576,1605]],[[64521,64521],\\\"mapped\\\",[1576,1609]],[[64522,64522],\\\"mapped\\\",[1576,1610]],[[64523,64523],\\\"mapped\\\",[1578,1580]],[[64524,64524],\\\"mapped\\\",[1578,1581]],[[64525,64525],\\\"mapped\\\",[1578,1582]],[[64526,64526],\\\"mapped\\\",[1578,1605]],[[64527,64527],\\\"mapped\\\",[1578,1609]],[[64528,64528],\\\"mapped\\\",[1578,1610]],[[64529,64529],\\\"mapped\\\",[1579,1580]],[[64530,64530],\\\"mapped\\\",[1579,1605]],[[64531,64531],\\\"mapped\\\",[1579,1609]],[[64532,64532],\\\"mapped\\\",[1579,1610]],[[64533,64533],\\\"mapped\\\",[1580,1581]],[[64534,64534],\\\"mapped\\\",[1580,1605]],[[64535,64535],\\\"mapped\\\",[1581,1580]],[[64536,64536],\\\"mapped\\\",[1581,1605]],[[64537,64537],\\\"mapped\\\",[1582,1580]],[[64538,64538],\\\"mapped\\\",[1582,1581]],[[64539,64539],\\\"mapped\\\",[1582,1605]],[[64540,64540],\\\"mapped\\\",[1587,1580]],[[64541,64541],\\\"mapped\\\",[1587,1581]],[[64542,64542],\\\"mapped\\\",[1587,1582]],[[64543,64543],\\\"mapped\\\",[1587,1605]],[[64544,64544],\\\"mapped\\\",[1589,1581]],[[64545,64545],\\\"mapped\\\",[1589,1605]],[[64546,64546],\\\"mapped\\\",[1590,1580]],[[64547,64547],\\\"mapped\\\",[1590,1581]],[[64548,64548],\\\"mapped\\\",[1590,1582]],[[64549,64549],\\\"mapped\\\",[1590,1605]],[[64550,64550],\\\"mapped\\\",[1591,1581]],[[64551,64551],\\\"mapped\\\",[1591,1605]],[[64552,64552],\\\"mapped\\\",[1592,1605]],[[64553,64553],\\\"mapped\\\",[1593,1580]],[[64554,64554],\\\"mapped\\\",[1593,1605]],[[64555,64555],\\\"mapped\\\",[1594,1580]],[[64556,64556],\\\"mapped\\\",[1594,1605]],[[64557,64557],\\\"mapped\\\",[1601,1580]],[[64558,64558],\\\"mapped\\\",[1601,1581]],[[64559,64559],\\\"mapped\\\",[1601,1582]],[[64560,64560],\\\"mapped\\\",[1601,1605]],[[64561,64561],\\\"mapped\\\",[1601,1609]],[[64562,64562],\\\"mapped\\\",[1601,1610]],[[64563,64563],\\\"mapped\\\",[1602,1581]],[[64564,64564],\\\"mapped\\\",[1602,1605]],[[64565,64565],\\\"mapped\\\",[1602,1609]],[[64566,64566],\\\"mapped\\\",[1602,1610]],[[64567,64567],\\\"mapped\\\",[1603,1575]],[[64568,64568],\\\"mapped\\\",[1603,1580]],[[64569,64569],\\\"mapped\\\",[1603,1581]],[[64570,64570],\\\"mapped\\\",[1603,1582]],[[64571,64571],\\\"mapped\\\",[1603,1604]],[[64572,64572],\\\"mapped\\\",[1603,1605]],[[64573,64573],\\\"mapped\\\",[1603,1609]],[[64574,64574],\\\"mapped\\\",[1603,1610]],[[64575,64575],\\\"mapped\\\",[1604,1580]],[[64576,64576],\\\"mapped\\\",[1604,1581]],[[64577,64577],\\\"mapped\\\",[1604,1582]],[[64578,64578],\\\"mapped\\\",[1604,1605]],[[64579,64579],\\\"mapped\\\",[1604,1609]],[[64580,64580],\\\"mapped\\\",[1604,1610]],[[64581,64581],\\\"mapped\\\",[1605,1580]],[[64582,64582],\\\"mapped\\\",[1605,1581]],[[64583,64583],\\\"mapped\\\",[1605,1582]],[[64584,64584],\\\"mapped\\\",[1605,1605]],[[64585,64585],\\\"mapped\\\",[1605,1609]],[[64586,64586],\\\"mapped\\\",[1605,1610]],[[64587,64587],\\\"mapped\\\",[1606,1580]],[[64588,64588],\\\"mapped\\\",[1606,1581]],[[64589,64589],\\\"mapped\\\",[1606,1582]],[[64590,64590],\\\"mapped\\\",[1606,1605]],[[64591,64591],\\\"mapped\\\",[1606,1609]],[[64592,64592],\\\"mapped\\\",[1606,1610]],[[64593,64593],\\\"mapped\\\",[1607,1580]],[[64594,64594],\\\"mapped\\\",[1607,1605]],[[64595,64595],\\\"mapped\\\",[1607,1609]],[[64596,64596],\\\"mapped\\\",[1607,1610]],[[64597,64597],\\\"mapped\\\",[1610,1580]],[[64598,64598],\\\"mapped\\\",[1610,1581]],[[64599,64599],\\\"mapped\\\",[1610,1582]],[[64600,64600],\\\"mapped\\\",[1610,1605]],[[64601,64601],\\\"mapped\\\",[1610,1609]],[[64602,64602],\\\"mapped\\\",[1610,1610]],[[64603,64603],\\\"mapped\\\",[1584,1648]],[[64604,64604],\\\"mapped\\\",[1585,1648]],[[64605,64605],\\\"mapped\\\",[1609,1648]],[[64606,64606],\\\"disallowed_STD3_mapped\\\",[32,1612,1617]],[[64607,64607],\\\"disallowed_STD3_mapped\\\",[32,1613,1617]],[[64608,64608],\\\"disallowed_STD3_mapped\\\",[32,1614,1617]],[[64609,64609],\\\"disallowed_STD3_mapped\\\",[32,1615,1617]],[[64610,64610],\\\"disallowed_STD3_mapped\\\",[32,1616,1617]],[[64611,64611],\\\"disallowed_STD3_mapped\\\",[32,1617,1648]],[[64612,64612],\\\"mapped\\\",[1574,1585]],[[64613,64613],\\\"mapped\\\",[1574,1586]],[[64614,64614],\\\"mapped\\\",[1574,1605]],[[64615,64615],\\\"mapped\\\",[1574,1606]],[[64616,64616],\\\"mapped\\\",[1574,1609]],[[64617,64617],\\\"mapped\\\",[1574,1610]],[[64618,64618],\\\"mapped\\\",[1576,1585]],[[64619,64619],\\\"mapped\\\",[1576,1586]],[[64620,64620],\\\"mapped\\\",[1576,1605]],[[64621,64621],\\\"mapped\\\",[1576,1606]],[[64622,64622],\\\"mapped\\\",[1576,1609]],[[64623,64623],\\\"mapped\\\",[1576,1610]],[[64624,64624],\\\"mapped\\\",[1578,1585]],[[64625,64625],\\\"mapped\\\",[1578,1586]],[[64626,64626],\\\"mapped\\\",[1578,1605]],[[64627,64627],\\\"mapped\\\",[1578,1606]],[[64628,64628],\\\"mapped\\\",[1578,1609]],[[64629,64629],\\\"mapped\\\",[1578,1610]],[[64630,64630],\\\"mapped\\\",[1579,1585]],[[64631,64631],\\\"mapped\\\",[1579,1586]],[[64632,64632],\\\"mapped\\\",[1579,1605]],[[64633,64633],\\\"mapped\\\",[1579,1606]],[[64634,64634],\\\"mapped\\\",[1579,1609]],[[64635,64635],\\\"mapped\\\",[1579,1610]],[[64636,64636],\\\"mapped\\\",[1601,1609]],[[64637,64637],\\\"mapped\\\",[1601,1610]],[[64638,64638],\\\"mapped\\\",[1602,1609]],[[64639,64639],\\\"mapped\\\",[1602,1610]],[[64640,64640],\\\"mapped\\\",[1603,1575]],[[64641,64641],\\\"mapped\\\",[1603,1604]],[[64642,64642],\\\"mapped\\\",[1603,1605]],[[64643,64643],\\\"mapped\\\",[1603,1609]],[[64644,64644],\\\"mapped\\\",[1603,1610]],[[64645,64645],\\\"mapped\\\",[1604,1605]],[[64646,64646],\\\"mapped\\\",[1604,1609]],[[64647,64647],\\\"mapped\\\",[1604,1610]],[[64648,64648],\\\"mapped\\\",[1605,1575]],[[64649,64649],\\\"mapped\\\",[1605,1605]],[[64650,64650],\\\"mapped\\\",[1606,1585]],[[64651,64651],\\\"mapped\\\",[1606,1586]],[[64652,64652],\\\"mapped\\\",[1606,1605]],[[64653,64653],\\\"mapped\\\",[1606,1606]],[[64654,64654],\\\"mapped\\\",[1606,1609]],[[64655,64655],\\\"mapped\\\",[1606,1610]],[[64656,64656],\\\"mapped\\\",[1609,1648]],[[64657,64657],\\\"mapped\\\",[1610,1585]],[[64658,64658],\\\"mapped\\\",[1610,1586]],[[64659,64659],\\\"mapped\\\",[1610,1605]],[[64660,64660],\\\"mapped\\\",[1610,1606]],[[64661,64661],\\\"mapped\\\",[1610,1609]],[[64662,64662],\\\"mapped\\\",[1610,1610]],[[64663,64663],\\\"mapped\\\",[1574,1580]],[[64664,64664],\\\"mapped\\\",[1574,1581]],[[64665,64665],\\\"mapped\\\",[1574,1582]],[[64666,64666],\\\"mapped\\\",[1574,1605]],[[64667,64667],\\\"mapped\\\",[1574,1607]],[[64668,64668],\\\"mapped\\\",[1576,1580]],[[64669,64669],\\\"mapped\\\",[1576,1581]],[[64670,64670],\\\"mapped\\\",[1576,1582]],[[64671,64671],\\\"mapped\\\",[1576,1605]],[[64672,64672],\\\"mapped\\\",[1576,1607]],[[64673,64673],\\\"mapped\\\",[1578,1580]],[[64674,64674],\\\"mapped\\\",[1578,1581]],[[64675,64675],\\\"mapped\\\",[1578,1582]],[[64676,64676],\\\"mapped\\\",[1578,1605]],[[64677,64677],\\\"mapped\\\",[1578,1607]],[[64678,64678],\\\"mapped\\\",[1579,1605]],[[64679,64679],\\\"mapped\\\",[1580,1581]],[[64680,64680],\\\"mapped\\\",[1580,1605]],[[64681,64681],\\\"mapped\\\",[1581,1580]],[[64682,64682],\\\"mapped\\\",[1581,1605]],[[64683,64683],\\\"mapped\\\",[1582,1580]],[[64684,64684],\\\"mapped\\\",[1582,1605]],[[64685,64685],\\\"mapped\\\",[1587,1580]],[[64686,64686],\\\"mapped\\\",[1587,1581]],[[64687,64687],\\\"mapped\\\",[1587,1582]],[[64688,64688],\\\"mapped\\\",[1587,1605]],[[64689,64689],\\\"mapped\\\",[1589,1581]],[[64690,64690],\\\"mapped\\\",[1589,1582]],[[64691,64691],\\\"mapped\\\",[1589,1605]],[[64692,64692],\\\"mapped\\\",[1590,1580]],[[64693,64693],\\\"mapped\\\",[1590,1581]],[[64694,64694],\\\"mapped\\\",[1590,1582]],[[64695,64695],\\\"mapped\\\",[1590,1605]],[[64696,64696],\\\"mapped\\\",[1591,1581]],[[64697,64697],\\\"mapped\\\",[1592,1605]],[[64698,64698],\\\"mapped\\\",[1593,1580]],[[64699,64699],\\\"mapped\\\",[1593,1605]],[[64700,64700],\\\"mapped\\\",[1594,1580]],[[64701,64701],\\\"mapped\\\",[1594,1605]],[[64702,64702],\\\"mapped\\\",[1601,1580]],[[64703,64703],\\\"mapped\\\",[1601,1581]],[[64704,64704],\\\"mapped\\\",[1601,1582]],[[64705,64705],\\\"mapped\\\",[1601,1605]],[[64706,64706],\\\"mapped\\\",[1602,1581]],[[64707,64707],\\\"mapped\\\",[1602,1605]],[[64708,64708],\\\"mapped\\\",[1603,1580]],[[64709,64709],\\\"mapped\\\",[1603,1581]],[[64710,64710],\\\"mapped\\\",[1603,1582]],[[64711,64711],\\\"mapped\\\",[1603,1604]],[[64712,64712],\\\"mapped\\\",[1603,1605]],[[64713,64713],\\\"mapped\\\",[1604,1580]],[[64714,64714],\\\"mapped\\\",[1604,1581]],[[64715,64715],\\\"mapped\\\",[1604,1582]],[[64716,64716],\\\"mapped\\\",[1604,1605]],[[64717,64717],\\\"mapped\\\",[1604,1607]],[[64718,64718],\\\"mapped\\\",[1605,1580]],[[64719,64719],\\\"mapped\\\",[1605,1581]],[[64720,64720],\\\"mapped\\\",[1605,1582]],[[64721,64721],\\\"mapped\\\",[1605,1605]],[[64722,64722],\\\"mapped\\\",[1606,1580]],[[64723,64723],\\\"mapped\\\",[1606,1581]],[[64724,64724],\\\"mapped\\\",[1606,1582]],[[64725,64725],\\\"mapped\\\",[1606,1605]],[[64726,64726],\\\"mapped\\\",[1606,1607]],[[64727,64727],\\\"mapped\\\",[1607,1580]],[[64728,64728],\\\"mapped\\\",[1607,1605]],[[64729,64729],\\\"mapped\\\",[1607,1648]],[[64730,64730],\\\"mapped\\\",[1610,1580]],[[64731,64731],\\\"mapped\\\",[1610,1581]],[[64732,64732],\\\"mapped\\\",[1610,1582]],[[64733,64733],\\\"mapped\\\",[1610,1605]],[[64734,64734],\\\"mapped\\\",[1610,1607]],[[64735,64735],\\\"mapped\\\",[1574,1605]],[[64736,64736],\\\"mapped\\\",[1574,1607]],[[64737,64737],\\\"mapped\\\",[1576,1605]],[[64738,64738],\\\"mapped\\\",[1576,1607]],[[64739,64739],\\\"mapped\\\",[1578,1605]],[[64740,64740],\\\"mapped\\\",[1578,1607]],[[64741,64741],\\\"mapped\\\",[1579,1605]],[[64742,64742],\\\"mapped\\\",[1579,1607]],[[64743,64743],\\\"mapped\\\",[1587,1605]],[[64744,64744],\\\"mapped\\\",[1587,1607]],[[64745,64745],\\\"mapped\\\",[1588,1605]],[[64746,64746],\\\"mapped\\\",[1588,1607]],[[64747,64747],\\\"mapped\\\",[1603,1604]],[[64748,64748],\\\"mapped\\\",[1603,1605]],[[64749,64749],\\\"mapped\\\",[1604,1605]],[[64750,64750],\\\"mapped\\\",[1606,1605]],[[64751,64751],\\\"mapped\\\",[1606,1607]],[[64752,64752],\\\"mapped\\\",[1610,1605]],[[64753,64753],\\\"mapped\\\",[1610,1607]],[[64754,64754],\\\"mapped\\\",[1600,1614,1617]],[[64755,64755],\\\"mapped\\\",[1600,1615,1617]],[[64756,64756],\\\"mapped\\\",[1600,1616,1617]],[[64757,64757],\\\"mapped\\\",[1591,1609]],[[64758,64758],\\\"mapped\\\",[1591,1610]],[[64759,64759],\\\"mapped\\\",[1593,1609]],[[64760,64760],\\\"mapped\\\",[1593,1610]],[[64761,64761],\\\"mapped\\\",[1594,1609]],[[64762,64762],\\\"mapped\\\",[1594,1610]],[[64763,64763],\\\"mapped\\\",[1587,1609]],[[64764,64764],\\\"mapped\\\",[1587,1610]],[[64765,64765],\\\"mapped\\\",[1588,1609]],[[64766,64766],\\\"mapped\\\",[1588,1610]],[[64767,64767],\\\"mapped\\\",[1581,1609]],[[64768,64768],\\\"mapped\\\",[1581,1610]],[[64769,64769],\\\"mapped\\\",[1580,1609]],[[64770,64770],\\\"mapped\\\",[1580,1610]],[[64771,64771],\\\"mapped\\\",[1582,1609]],[[64772,64772],\\\"mapped\\\",[1582,1610]],[[64773,64773],\\\"mapped\\\",[1589,1609]],[[64774,64774],\\\"mapped\\\",[1589,1610]],[[64775,64775],\\\"mapped\\\",[1590,1609]],[[64776,64776],\\\"mapped\\\",[1590,1610]],[[64777,64777],\\\"mapped\\\",[1588,1580]],[[64778,64778],\\\"mapped\\\",[1588,1581]],[[64779,64779],\\\"mapped\\\",[1588,1582]],[[64780,64780],\\\"mapped\\\",[1588,1605]],[[64781,64781],\\\"mapped\\\",[1588,1585]],[[64782,64782],\\\"mapped\\\",[1587,1585]],[[64783,64783],\\\"mapped\\\",[1589,1585]],[[64784,64784],\\\"mapped\\\",[1590,1585]],[[64785,64785],\\\"mapped\\\",[1591,1609]],[[64786,64786],\\\"mapped\\\",[1591,1610]],[[64787,64787],\\\"mapped\\\",[1593,1609]],[[64788,64788],\\\"mapped\\\",[1593,1610]],[[64789,64789],\\\"mapped\\\",[1594,1609]],[[64790,64790],\\\"mapped\\\",[1594,1610]],[[64791,64791],\\\"mapped\\\",[1587,1609]],[[64792,64792],\\\"mapped\\\",[1587,1610]],[[64793,64793],\\\"mapped\\\",[1588,1609]],[[64794,64794],\\\"mapped\\\",[1588,1610]],[[64795,64795],\\\"mapped\\\",[1581,1609]],[[64796,64796],\\\"mapped\\\",[1581,1610]],[[64797,64797],\\\"mapped\\\",[1580,1609]],[[64798,64798],\\\"mapped\\\",[1580,1610]],[[64799,64799],\\\"mapped\\\",[1582,1609]],[[64800,64800],\\\"mapped\\\",[1582,1610]],[[64801,64801],\\\"mapped\\\",[1589,1609]],[[64802,64802],\\\"mapped\\\",[1589,1610]],[[64803,64803],\\\"mapped\\\",[1590,1609]],[[64804,64804],\\\"mapped\\\",[1590,1610]],[[64805,64805],\\\"mapped\\\",[1588,1580]],[[64806,64806],\\\"mapped\\\",[1588,1581]],[[64807,64807],\\\"mapped\\\",[1588,1582]],[[64808,64808],\\\"mapped\\\",[1588,1605]],[[64809,64809],\\\"mapped\\\",[1588,1585]],[[64810,64810],\\\"mapped\\\",[1587,1585]],[[64811,64811],\\\"mapped\\\",[1589,1585]],[[64812,64812],\\\"mapped\\\",[1590,1585]],[[64813,64813],\\\"mapped\\\",[1588,1580]],[[64814,64814],\\\"mapped\\\",[1588,1581]],[[64815,64815],\\\"mapped\\\",[1588,1582]],[[64816,64816],\\\"mapped\\\",[1588,1605]],[[64817,64817],\\\"mapped\\\",[1587,1607]],[[64818,64818],\\\"mapped\\\",[1588,1607]],[[64819,64819],\\\"mapped\\\",[1591,1605]],[[64820,64820],\\\"mapped\\\",[1587,1580]],[[64821,64821],\\\"mapped\\\",[1587,1581]],[[64822,64822],\\\"mapped\\\",[1587,1582]],[[64823,64823],\\\"mapped\\\",[1588,1580]],[[64824,64824],\\\"mapped\\\",[1588,1581]],[[64825,64825],\\\"mapped\\\",[1588,1582]],[[64826,64826],\\\"mapped\\\",[1591,1605]],[[64827,64827],\\\"mapped\\\",[1592,1605]],[[64828,64829],\\\"mapped\\\",[1575,1611]],[[64830,64831],\\\"valid\\\",[],\\\"NV8\\\"],[[64832,64847],\\\"disallowed\\\"],[[64848,64848],\\\"mapped\\\",[1578,1580,1605]],[[64849,64850],\\\"mapped\\\",[1578,1581,1580]],[[64851,64851],\\\"mapped\\\",[1578,1581,1605]],[[64852,64852],\\\"mapped\\\",[1578,1582,1605]],[[64853,64853],\\\"mapped\\\",[1578,1605,1580]],[[64854,64854],\\\"mapped\\\",[1578,1605,1581]],[[64855,64855],\\\"mapped\\\",[1578,1605,1582]],[[64856,64857],\\\"mapped\\\",[1580,1605,1581]],[[64858,64858],\\\"mapped\\\",[1581,1605,1610]],[[64859,64859],\\\"mapped\\\",[1581,1605,1609]],[[64860,64860],\\\"mapped\\\",[1587,1581,1580]],[[64861,64861],\\\"mapped\\\",[1587,1580,1581]],[[64862,64862],\\\"mapped\\\",[1587,1580,1609]],[[64863,64864],\\\"mapped\\\",[1587,1605,1581]],[[64865,64865],\\\"mapped\\\",[1587,1605,1580]],[[64866,64867],\\\"mapped\\\",[1587,1605,1605]],[[64868,64869],\\\"mapped\\\",[1589,1581,1581]],[[64870,64870],\\\"mapped\\\",[1589,1605,1605]],[[64871,64872],\\\"mapped\\\",[1588,1581,1605]],[[64873,64873],\\\"mapped\\\",[1588,1580,1610]],[[64874,64875],\\\"mapped\\\",[1588,1605,1582]],[[64876,64877],\\\"mapped\\\",[1588,1605,1605]],[[64878,64878],\\\"mapped\\\",[1590,1581,1609]],[[64879,64880],\\\"mapped\\\",[1590,1582,1605]],[[64881,64882],\\\"mapped\\\",[1591,1605,1581]],[[64883,64883],\\\"mapped\\\",[1591,1605,1605]],[[64884,64884],\\\"mapped\\\",[1591,1605,1610]],[[64885,64885],\\\"mapped\\\",[1593,1580,1605]],[[64886,64887],\\\"mapped\\\",[1593,1605,1605]],[[64888,64888],\\\"mapped\\\",[1593,1605,1609]],[[64889,64889],\\\"mapped\\\",[1594,1605,1605]],[[64890,64890],\\\"mapped\\\",[1594,1605,1610]],[[64891,64891],\\\"mapped\\\",[1594,1605,1609]],[[64892,64893],\\\"mapped\\\",[1601,1582,1605]],[[64894,64894],\\\"mapped\\\",[1602,1605,1581]],[[64895,64895],\\\"mapped\\\",[1602,1605,1605]],[[64896,64896],\\\"mapped\\\",[1604,1581,1605]],[[64897,64897],\\\"mapped\\\",[1604,1581,1610]],[[64898,64898],\\\"mapped\\\",[1604,1581,1609]],[[64899,64900],\\\"mapped\\\",[1604,1580,1580]],[[64901,64902],\\\"mapped\\\",[1604,1582,1605]],[[64903,64904],\\\"mapped\\\",[1604,1605,1581]],[[64905,64905],\\\"mapped\\\",[1605,1581,1580]],[[64906,64906],\\\"mapped\\\",[1605,1581,1605]],[[64907,64907],\\\"mapped\\\",[1605,1581,1610]],[[64908,64908],\\\"mapped\\\",[1605,1580,1581]],[[64909,64909],\\\"mapped\\\",[1605,1580,1605]],[[64910,64910],\\\"mapped\\\",[1605,1582,1580]],[[64911,64911],\\\"mapped\\\",[1605,1582,1605]],[[64912,64913],\\\"disallowed\\\"],[[64914,64914],\\\"mapped\\\",[1605,1580,1582]],[[64915,64915],\\\"mapped\\\",[1607,1605,1580]],[[64916,64916],\\\"mapped\\\",[1607,1605,1605]],[[64917,64917],\\\"mapped\\\",[1606,1581,1605]],[[64918,64918],\\\"mapped\\\",[1606,1581,1609]],[[64919,64920],\\\"mapped\\\",[1606,1580,1605]],[[64921,64921],\\\"mapped\\\",[1606,1580,1609]],[[64922,64922],\\\"mapped\\\",[1606,1605,1610]],[[64923,64923],\\\"mapped\\\",[1606,1605,1609]],[[64924,64925],\\\"mapped\\\",[1610,1605,1605]],[[64926,64926],\\\"mapped\\\",[1576,1582,1610]],[[64927,64927],\\\"mapped\\\",[1578,1580,1610]],[[64928,64928],\\\"mapped\\\",[1578,1580,1609]],[[64929,64929],\\\"mapped\\\",[1578,1582,1610]],[[64930,64930],\\\"mapped\\\",[1578,1582,1609]],[[64931,64931],\\\"mapped\\\",[1578,1605,1610]],[[64932,64932],\\\"mapped\\\",[1578,1605,1609]],[[64933,64933],\\\"mapped\\\",[1580,1605,1610]],[[64934,64934],\\\"mapped\\\",[1580,1581,1609]],[[64935,64935],\\\"mapped\\\",[1580,1605,1609]],[[64936,64936],\\\"mapped\\\",[1587,1582,1609]],[[64937,64937],\\\"mapped\\\",[1589,1581,1610]],[[64938,64938],\\\"mapped\\\",[1588,1581,1610]],[[64939,64939],\\\"mapped\\\",[1590,1581,1610]],[[64940,64940],\\\"mapped\\\",[1604,1580,1610]],[[64941,64941],\\\"mapped\\\",[1604,1605,1610]],[[64942,64942],\\\"mapped\\\",[1610,1581,1610]],[[64943,64943],\\\"mapped\\\",[1610,1580,1610]],[[64944,64944],\\\"mapped\\\",[1610,1605,1610]],[[64945,64945],\\\"mapped\\\",[1605,1605,1610]],[[64946,64946],\\\"mapped\\\",[1602,1605,1610]],[[64947,64947],\\\"mapped\\\",[1606,1581,1610]],[[64948,64948],\\\"mapped\\\",[1602,1605,1581]],[[64949,64949],\\\"mapped\\\",[1604,1581,1605]],[[64950,64950],\\\"mapped\\\",[1593,1605,1610]],[[64951,64951],\\\"mapped\\\",[1603,1605,1610]],[[64952,64952],\\\"mapped\\\",[1606,1580,1581]],[[64953,64953],\\\"mapped\\\",[1605,1582,1610]],[[64954,64954],\\\"mapped\\\",[1604,1580,1605]],[[64955,64955],\\\"mapped\\\",[1603,1605,1605]],[[64956,64956],\\\"mapped\\\",[1604,1580,1605]],[[64957,64957],\\\"mapped\\\",[1606,1580,1581]],[[64958,64958],\\\"mapped\\\",[1580,1581,1610]],[[64959,64959],\\\"mapped\\\",[1581,1580,1610]],[[64960,64960],\\\"mapped\\\",[1605,1580,1610]],[[64961,64961],\\\"mapped\\\",[1601,1605,1610]],[[64962,64962],\\\"mapped\\\",[1576,1581,1610]],[[64963,64963],\\\"mapped\\\",[1603,1605,1605]],[[64964,64964],\\\"mapped\\\",[1593,1580,1605]],[[64965,64965],\\\"mapped\\\",[1589,1605,1605]],[[64966,64966],\\\"mapped\\\",[1587,1582,1610]],[[64967,64967],\\\"mapped\\\",[1606,1580,1610]],[[64968,64975],\\\"disallowed\\\"],[[64976,65007],\\\"disallowed\\\"],[[65008,65008],\\\"mapped\\\",[1589,1604,1746]],[[65009,65009],\\\"mapped\\\",[1602,1604,1746]],[[65010,65010],\\\"mapped\\\",[1575,1604,1604,1607]],[[65011,65011],\\\"mapped\\\",[1575,1603,1576,1585]],[[65012,65012],\\\"mapped\\\",[1605,1581,1605,1583]],[[65013,65013],\\\"mapped\\\",[1589,1604,1593,1605]],[[65014,65014],\\\"mapped\\\",[1585,1587,1608,1604]],[[65015,65015],\\\"mapped\\\",[1593,1604,1610,1607]],[[65016,65016],\\\"mapped\\\",[1608,1587,1604,1605]],[[65017,65017],\\\"mapped\\\",[1589,1604,1609]],[[65018,65018],\\\"disallowed_STD3_mapped\\\",[1589,1604,1609,32,1575,1604,1604,1607,32,1593,1604,1610,1607,32,1608,1587,1604,1605]],[[65019,65019],\\\"disallowed_STD3_mapped\\\",[1580,1604,32,1580,1604,1575,1604,1607]],[[65020,65020],\\\"mapped\\\",[1585,1740,1575,1604]],[[65021,65021],\\\"valid\\\",[],\\\"NV8\\\"],[[65022,65023],\\\"disallowed\\\"],[[65024,65039],\\\"ignored\\\"],[[65040,65040],\\\"disallowed_STD3_mapped\\\",[44]],[[65041,65041],\\\"mapped\\\",[12289]],[[65042,65042],\\\"disallowed\\\"],[[65043,65043],\\\"disallowed_STD3_mapped\\\",[58]],[[65044,65044],\\\"disallowed_STD3_mapped\\\",[59]],[[65045,65045],\\\"disallowed_STD3_mapped\\\",[33]],[[65046,65046],\\\"disallowed_STD3_mapped\\\",[63]],[[65047,65047],\\\"mapped\\\",[12310]],[[65048,65048],\\\"mapped\\\",[12311]],[[65049,65049],\\\"disallowed\\\"],[[65050,65055],\\\"disallowed\\\"],[[65056,65059],\\\"valid\\\"],[[65060,65062],\\\"valid\\\"],[[65063,65069],\\\"valid\\\"],[[65070,65071],\\\"valid\\\"],[[65072,65072],\\\"disallowed\\\"],[[65073,65073],\\\"mapped\\\",[8212]],[[65074,65074],\\\"mapped\\\",[8211]],[[65075,65076],\\\"disallowed_STD3_mapped\\\",[95]],[[65077,65077],\\\"disallowed_STD3_mapped\\\",[40]],[[65078,65078],\\\"disallowed_STD3_mapped\\\",[41]],[[65079,65079],\\\"disallowed_STD3_mapped\\\",[123]],[[65080,65080],\\\"disallowed_STD3_mapped\\\",[125]],[[65081,65081],\\\"mapped\\\",[12308]],[[65082,65082],\\\"mapped\\\",[12309]],[[65083,65083],\\\"mapped\\\",[12304]],[[65084,65084],\\\"mapped\\\",[12305]],[[65085,65085],\\\"mapped\\\",[12298]],[[65086,65086],\\\"mapped\\\",[12299]],[[65087,65087],\\\"mapped\\\",[12296]],[[65088,65088],\\\"mapped\\\",[12297]],[[65089,65089],\\\"mapped\\\",[12300]],[[65090,65090],\\\"mapped\\\",[12301]],[[65091,65091],\\\"mapped\\\",[12302]],[[65092,65092],\\\"mapped\\\",[12303]],[[65093,65094],\\\"valid\\\",[],\\\"NV8\\\"],[[65095,65095],\\\"disallowed_STD3_mapped\\\",[91]],[[65096,65096],\\\"disallowed_STD3_mapped\\\",[93]],[[65097,65100],\\\"disallowed_STD3_mapped\\\",[32,773]],[[65101,65103],\\\"disallowed_STD3_mapped\\\",[95]],[[65104,65104],\\\"disallowed_STD3_mapped\\\",[44]],[[65105,65105],\\\"mapped\\\",[12289]],[[65106,65106],\\\"disallowed\\\"],[[65107,65107],\\\"disallowed\\\"],[[65108,65108],\\\"disallowed_STD3_mapped\\\",[59]],[[65109,65109],\\\"disallowed_STD3_mapped\\\",[58]],[[65110,65110],\\\"disallowed_STD3_mapped\\\",[63]],[[65111,65111],\\\"disallowed_STD3_mapped\\\",[33]],[[65112,65112],\\\"mapped\\\",[8212]],[[65113,65113],\\\"disallowed_STD3_mapped\\\",[40]],[[65114,65114],\\\"disallowed_STD3_mapped\\\",[41]],[[65115,65115],\\\"disallowed_STD3_mapped\\\",[123]],[[65116,65116],\\\"disallowed_STD3_mapped\\\",[125]],[[65117,65117],\\\"mapped\\\",[12308]],[[65118,65118],\\\"mapped\\\",[12309]],[[65119,65119],\\\"disallowed_STD3_mapped\\\",[35]],[[65120,65120],\\\"disallowed_STD3_mapped\\\",[38]],[[65121,65121],\\\"disallowed_STD3_mapped\\\",[42]],[[65122,65122],\\\"disallowed_STD3_mapped\\\",[43]],[[65123,65123],\\\"mapped\\\",[45]],[[65124,65124],\\\"disallowed_STD3_mapped\\\",[60]],[[65125,65125],\\\"disallowed_STD3_mapped\\\",[62]],[[65126,65126],\\\"disallowed_STD3_mapped\\\",[61]],[[65127,65127],\\\"disallowed\\\"],[[65128,65128],\\\"disallowed_STD3_mapped\\\",[92]],[[65129,65129],\\\"disallowed_STD3_mapped\\\",[36]],[[65130,65130],\\\"disallowed_STD3_mapped\\\",[37]],[[65131,65131],\\\"disallowed_STD3_mapped\\\",[64]],[[65132,65135],\\\"disallowed\\\"],[[65136,65136],\\\"disallowed_STD3_mapped\\\",[32,1611]],[[65137,65137],\\\"mapped\\\",[1600,1611]],[[65138,65138],\\\"disallowed_STD3_mapped\\\",[32,1612]],[[65139,65139],\\\"valid\\\"],[[65140,65140],\\\"disallowed_STD3_mapped\\\",[32,1613]],[[65141,65141],\\\"disallowed\\\"],[[65142,65142],\\\"disallowed_STD3_mapped\\\",[32,1614]],[[65143,65143],\\\"mapped\\\",[1600,1614]],[[65144,65144],\\\"disallowed_STD3_mapped\\\",[32,1615]],[[65145,65145],\\\"mapped\\\",[1600,1615]],[[65146,65146],\\\"disallowed_STD3_mapped\\\",[32,1616]],[[65147,65147],\\\"mapped\\\",[1600,1616]],[[65148,65148],\\\"disallowed_STD3_mapped\\\",[32,1617]],[[65149,65149],\\\"mapped\\\",[1600,1617]],[[65150,65150],\\\"disallowed_STD3_mapped\\\",[32,1618]],[[65151,65151],\\\"mapped\\\",[1600,1618]],[[65152,65152],\\\"mapped\\\",[1569]],[[65153,65154],\\\"mapped\\\",[1570]],[[65155,65156],\\\"mapped\\\",[1571]],[[65157,65158],\\\"mapped\\\",[1572]],[[65159,65160],\\\"mapped\\\",[1573]],[[65161,65164],\\\"mapped\\\",[1574]],[[65165,65166],\\\"mapped\\\",[1575]],[[65167,65170],\\\"mapped\\\",[1576]],[[65171,65172],\\\"mapped\\\",[1577]],[[65173,65176],\\\"mapped\\\",[1578]],[[65177,65180],\\\"mapped\\\",[1579]],[[65181,65184],\\\"mapped\\\",[1580]],[[65185,65188],\\\"mapped\\\",[1581]],[[65189,65192],\\\"mapped\\\",[1582]],[[65193,65194],\\\"mapped\\\",[1583]],[[65195,65196],\\\"mapped\\\",[1584]],[[65197,65198],\\\"mapped\\\",[1585]],[[65199,65200],\\\"mapped\\\",[1586]],[[65201,65204],\\\"mapped\\\",[1587]],[[65205,65208],\\\"mapped\\\",[1588]],[[65209,65212],\\\"mapped\\\",[1589]],[[65213,65216],\\\"mapped\\\",[1590]],[[65217,65220],\\\"mapped\\\",[1591]],[[65221,65224],\\\"mapped\\\",[1592]],[[65225,65228],\\\"mapped\\\",[1593]],[[65229,65232],\\\"mapped\\\",[1594]],[[65233,65236],\\\"mapped\\\",[1601]],[[65237,65240],\\\"mapped\\\",[1602]],[[65241,65244],\\\"mapped\\\",[1603]],[[65245,65248],\\\"mapped\\\",[1604]],[[65249,65252],\\\"mapped\\\",[1605]],[[65253,65256],\\\"mapped\\\",[1606]],[[65257,65260],\\\"mapped\\\",[1607]],[[65261,65262],\\\"mapped\\\",[1608]],[[65263,65264],\\\"mapped\\\",[1609]],[[65265,65268],\\\"mapped\\\",[1610]],[[65269,65270],\\\"mapped\\\",[1604,1570]],[[65271,65272],\\\"mapped\\\",[1604,1571]],[[65273,65274],\\\"mapped\\\",[1604,1573]],[[65275,65276],\\\"mapped\\\",[1604,1575]],[[65277,65278],\\\"disallowed\\\"],[[65279,65279],\\\"ignored\\\"],[[65280,65280],\\\"disallowed\\\"],[[65281,65281],\\\"disallowed_STD3_mapped\\\",[33]],[[65282,65282],\\\"disallowed_STD3_mapped\\\",[34]],[[65283,65283],\\\"disallowed_STD3_mapped\\\",[35]],[[65284,65284],\\\"disallowed_STD3_mapped\\\",[36]],[[65285,65285],\\\"disallowed_STD3_mapped\\\",[37]],[[65286,65286],\\\"disallowed_STD3_mapped\\\",[38]],[[65287,65287],\\\"disallowed_STD3_mapped\\\",[39]],[[65288,65288],\\\"disallowed_STD3_mapped\\\",[40]],[[65289,65289],\\\"disallowed_STD3_mapped\\\",[41]],[[65290,65290],\\\"disallowed_STD3_mapped\\\",[42]],[[65291,65291],\\\"disallowed_STD3_mapped\\\",[43]],[[65292,65292],\\\"disallowed_STD3_mapped\\\",[44]],[[65293,65293],\\\"mapped\\\",[45]],[[65294,65294],\\\"mapped\\\",[46]],[[65295,65295],\\\"disallowed_STD3_mapped\\\",[47]],[[65296,65296],\\\"mapped\\\",[48]],[[65297,65297],\\\"mapped\\\",[49]],[[65298,65298],\\\"mapped\\\",[50]],[[65299,65299],\\\"mapped\\\",[51]],[[65300,65300],\\\"mapped\\\",[52]],[[65301,65301],\\\"mapped\\\",[53]],[[65302,65302],\\\"mapped\\\",[54]],[[65303,65303],\\\"mapped\\\",[55]],[[65304,65304],\\\"mapped\\\",[56]],[[65305,65305],\\\"mapped\\\",[57]],[[65306,65306],\\\"disallowed_STD3_mapped\\\",[58]],[[65307,65307],\\\"disallowed_STD3_mapped\\\",[59]],[[65308,65308],\\\"disallowed_STD3_mapped\\\",[60]],[[65309,65309],\\\"disallowed_STD3_mapped\\\",[61]],[[65310,65310],\\\"disallowed_STD3_mapped\\\",[62]],[[65311,65311],\\\"disallowed_STD3_mapped\\\",[63]],[[65312,65312],\\\"disallowed_STD3_mapped\\\",[64]],[[65313,65313],\\\"mapped\\\",[97]],[[65314,65314],\\\"mapped\\\",[98]],[[65315,65315],\\\"mapped\\\",[99]],[[65316,65316],\\\"mapped\\\",[100]],[[65317,65317],\\\"mapped\\\",[101]],[[65318,65318],\\\"mapped\\\",[102]],[[65319,65319],\\\"mapped\\\",[103]],[[65320,65320],\\\"mapped\\\",[104]],[[65321,65321],\\\"mapped\\\",[105]],[[65322,65322],\\\"mapped\\\",[106]],[[65323,65323],\\\"mapped\\\",[107]],[[65324,65324],\\\"mapped\\\",[108]],[[65325,65325],\\\"mapped\\\",[109]],[[65326,65326],\\\"mapped\\\",[110]],[[65327,65327],\\\"mapped\\\",[111]],[[65328,65328],\\\"mapped\\\",[112]],[[65329,65329],\\\"mapped\\\",[113]],[[65330,65330],\\\"mapped\\\",[114]],[[65331,65331],\\\"mapped\\\",[115]],[[65332,65332],\\\"mapped\\\",[116]],[[65333,65333],\\\"mapped\\\",[117]],[[65334,65334],\\\"mapped\\\",[118]],[[65335,65335],\\\"mapped\\\",[119]],[[65336,65336],\\\"mapped\\\",[120]],[[65337,65337],\\\"mapped\\\",[121]],[[65338,65338],\\\"mapped\\\",[122]],[[65339,65339],\\\"disallowed_STD3_mapped\\\",[91]],[[65340,65340],\\\"disallowed_STD3_mapped\\\",[92]],[[65341,65341],\\\"disallowed_STD3_mapped\\\",[93]],[[65342,65342],\\\"disallowed_STD3_mapped\\\",[94]],[[65343,65343],\\\"disallowed_STD3_mapped\\\",[95]],[[65344,65344],\\\"disallowed_STD3_mapped\\\",[96]],[[65345,65345],\\\"mapped\\\",[97]],[[65346,65346],\\\"mapped\\\",[98]],[[65347,65347],\\\"mapped\\\",[99]],[[65348,65348],\\\"mapped\\\",[100]],[[65349,65349],\\\"mapped\\\",[101]],[[65350,65350],\\\"mapped\\\",[102]],[[65351,65351],\\\"mapped\\\",[103]],[[65352,65352],\\\"mapped\\\",[104]],[[65353,65353],\\\"mapped\\\",[105]],[[65354,65354],\\\"mapped\\\",[106]],[[65355,65355],\\\"mapped\\\",[107]],[[65356,65356],\\\"mapped\\\",[108]],[[65357,65357],\\\"mapped\\\",[109]],[[65358,65358],\\\"mapped\\\",[110]],[[65359,65359],\\\"mapped\\\",[111]],[[65360,65360],\\\"mapped\\\",[112]],[[65361,65361],\\\"mapped\\\",[113]],[[65362,65362],\\\"mapped\\\",[114]],[[65363,65363],\\\"mapped\\\",[115]],[[65364,65364],\\\"mapped\\\",[116]],[[65365,65365],\\\"mapped\\\",[117]],[[65366,65366],\\\"mapped\\\",[118]],[[65367,65367],\\\"mapped\\\",[119]],[[65368,65368],\\\"mapped\\\",[120]],[[65369,65369],\\\"mapped\\\",[121]],[[65370,65370],\\\"mapped\\\",[122]],[[65371,65371],\\\"disallowed_STD3_mapped\\\",[123]],[[65372,65372],\\\"disallowed_STD3_mapped\\\",[124]],[[65373,65373],\\\"disallowed_STD3_mapped\\\",[125]],[[65374,65374],\\\"disallowed_STD3_mapped\\\",[126]],[[65375,65375],\\\"mapped\\\",[10629]],[[65376,65376],\\\"mapped\\\",[10630]],[[65377,65377],\\\"mapped\\\",[46]],[[65378,65378],\\\"mapped\\\",[12300]],[[65379,65379],\\\"mapped\\\",[12301]],[[65380,65380],\\\"mapped\\\",[12289]],[[65381,65381],\\\"mapped\\\",[12539]],[[65382,65382],\\\"mapped\\\",[12530]],[[65383,65383],\\\"mapped\\\",[12449]],[[65384,65384],\\\"mapped\\\",[12451]],[[65385,65385],\\\"mapped\\\",[12453]],[[65386,65386],\\\"mapped\\\",[12455]],[[65387,65387],\\\"mapped\\\",[12457]],[[65388,65388],\\\"mapped\\\",[12515]],[[65389,65389],\\\"mapped\\\",[12517]],[[65390,65390],\\\"mapped\\\",[12519]],[[65391,65391],\\\"mapped\\\",[12483]],[[65392,65392],\\\"mapped\\\",[12540]],[[65393,65393],\\\"mapped\\\",[12450]],[[65394,65394],\\\"mapped\\\",[12452]],[[65395,65395],\\\"mapped\\\",[12454]],[[65396,65396],\\\"mapped\\\",[12456]],[[65397,65397],\\\"mapped\\\",[12458]],[[65398,65398],\\\"mapped\\\",[12459]],[[65399,65399],\\\"mapped\\\",[12461]],[[65400,65400],\\\"mapped\\\",[12463]],[[65401,65401],\\\"mapped\\\",[12465]],[[65402,65402],\\\"mapped\\\",[12467]],[[65403,65403],\\\"mapped\\\",[12469]],[[65404,65404],\\\"mapped\\\",[12471]],[[65405,65405],\\\"mapped\\\",[12473]],[[65406,65406],\\\"mapped\\\",[12475]],[[65407,65407],\\\"mapped\\\",[12477]],[[65408,65408],\\\"mapped\\\",[12479]],[[65409,65409],\\\"mapped\\\",[12481]],[[65410,65410],\\\"mapped\\\",[12484]],[[65411,65411],\\\"mapped\\\",[12486]],[[65412,65412],\\\"mapped\\\",[12488]],[[65413,65413],\\\"mapped\\\",[12490]],[[65414,65414],\\\"mapped\\\",[12491]],[[65415,65415],\\\"mapped\\\",[12492]],[[65416,65416],\\\"mapped\\\",[12493]],[[65417,65417],\\\"mapped\\\",[12494]],[[65418,65418],\\\"mapped\\\",[12495]],[[65419,65419],\\\"mapped\\\",[12498]],[[65420,65420],\\\"mapped\\\",[12501]],[[65421,65421],\\\"mapped\\\",[12504]],[[65422,65422],\\\"mapped\\\",[12507]],[[65423,65423],\\\"mapped\\\",[12510]],[[65424,65424],\\\"mapped\\\",[12511]],[[65425,65425],\\\"mapped\\\",[12512]],[[65426,65426],\\\"mapped\\\",[12513]],[[65427,65427],\\\"mapped\\\",[12514]],[[65428,65428],\\\"mapped\\\",[12516]],[[65429,65429],\\\"mapped\\\",[12518]],[[65430,65430],\\\"mapped\\\",[12520]],[[65431,65431],\\\"mapped\\\",[12521]],[[65432,65432],\\\"mapped\\\",[12522]],[[65433,65433],\\\"mapped\\\",[12523]],[[65434,65434],\\\"mapped\\\",[12524]],[[65435,65435],\\\"mapped\\\",[12525]],[[65436,65436],\\\"mapped\\\",[12527]],[[65437,65437],\\\"mapped\\\",[12531]],[[65438,65438],\\\"mapped\\\",[12441]],[[65439,65439],\\\"mapped\\\",[12442]],[[65440,65440],\\\"disallowed\\\"],[[65441,65441],\\\"mapped\\\",[4352]],[[65442,65442],\\\"mapped\\\",[4353]],[[65443,65443],\\\"mapped\\\",[4522]],[[65444,65444],\\\"mapped\\\",[4354]],[[65445,65445],\\\"mapped\\\",[4524]],[[65446,65446],\\\"mapped\\\",[4525]],[[65447,65447],\\\"mapped\\\",[4355]],[[65448,65448],\\\"mapped\\\",[4356]],[[65449,65449],\\\"mapped\\\",[4357]],[[65450,65450],\\\"mapped\\\",[4528]],[[65451,65451],\\\"mapped\\\",[4529]],[[65452,65452],\\\"mapped\\\",[4530]],[[65453,65453],\\\"mapped\\\",[4531]],[[65454,65454],\\\"mapped\\\",[4532]],[[65455,65455],\\\"mapped\\\",[4533]],[[65456,65456],\\\"mapped\\\",[4378]],[[65457,65457],\\\"mapped\\\",[4358]],[[65458,65458],\\\"mapped\\\",[4359]],[[65459,65459],\\\"mapped\\\",[4360]],[[65460,65460],\\\"mapped\\\",[4385]],[[65461,65461],\\\"mapped\\\",[4361]],[[65462,65462],\\\"mapped\\\",[4362]],[[65463,65463],\\\"mapped\\\",[4363]],[[65464,65464],\\\"mapped\\\",[4364]],[[65465,65465],\\\"mapped\\\",[4365]],[[65466,65466],\\\"mapped\\\",[4366]],[[65467,65467],\\\"mapped\\\",[4367]],[[65468,65468],\\\"mapped\\\",[4368]],[[65469,65469],\\\"mapped\\\",[4369]],[[65470,65470],\\\"mapped\\\",[4370]],[[65471,65473],\\\"disallowed\\\"],[[65474,65474],\\\"mapped\\\",[4449]],[[65475,65475],\\\"mapped\\\",[4450]],[[65476,65476],\\\"mapped\\\",[4451]],[[65477,65477],\\\"mapped\\\",[4452]],[[65478,65478],\\\"mapped\\\",[4453]],[[65479,65479],\\\"mapped\\\",[4454]],[[65480,65481],\\\"disallowed\\\"],[[65482,65482],\\\"mapped\\\",[4455]],[[65483,65483],\\\"mapped\\\",[4456]],[[65484,65484],\\\"mapped\\\",[4457]],[[65485,65485],\\\"mapped\\\",[4458]],[[65486,65486],\\\"mapped\\\",[4459]],[[65487,65487],\\\"mapped\\\",[4460]],[[65488,65489],\\\"disallowed\\\"],[[65490,65490],\\\"mapped\\\",[4461]],[[65491,65491],\\\"mapped\\\",[4462]],[[65492,65492],\\\"mapped\\\",[4463]],[[65493,65493],\\\"mapped\\\",[4464]],[[65494,65494],\\\"mapped\\\",[4465]],[[65495,65495],\\\"mapped\\\",[4466]],[[65496,65497],\\\"disallowed\\\"],[[65498,65498],\\\"mapped\\\",[4467]],[[65499,65499],\\\"mapped\\\",[4468]],[[65500,65500],\\\"mapped\\\",[4469]],[[65501,65503],\\\"disallowed\\\"],[[65504,65504],\\\"mapped\\\",[162]],[[65505,65505],\\\"mapped\\\",[163]],[[65506,65506],\\\"mapped\\\",[172]],[[65507,65507],\\\"disallowed_STD3_mapped\\\",[32,772]],[[65508,65508],\\\"mapped\\\",[166]],[[65509,65509],\\\"mapped\\\",[165]],[[65510,65510],\\\"mapped\\\",[8361]],[[65511,65511],\\\"disallowed\\\"],[[65512,65512],\\\"mapped\\\",[9474]],[[65513,65513],\\\"mapped\\\",[8592]],[[65514,65514],\\\"mapped\\\",[8593]],[[65515,65515],\\\"mapped\\\",[8594]],[[65516,65516],\\\"mapped\\\",[8595]],[[65517,65517],\\\"mapped\\\",[9632]],[[65518,65518],\\\"mapped\\\",[9675]],[[65519,65528],\\\"disallowed\\\"],[[65529,65531],\\\"disallowed\\\"],[[65532,65532],\\\"disallowed\\\"],[[65533,65533],\\\"disallowed\\\"],[[65534,65535],\\\"disallowed\\\"],[[65536,65547],\\\"valid\\\"],[[65548,65548],\\\"disallowed\\\"],[[65549,65574],\\\"valid\\\"],[[65575,65575],\\\"disallowed\\\"],[[65576,65594],\\\"valid\\\"],[[65595,65595],\\\"disallowed\\\"],[[65596,65597],\\\"valid\\\"],[[65598,65598],\\\"disallowed\\\"],[[65599,65613],\\\"valid\\\"],[[65614,65615],\\\"disallowed\\\"],[[65616,65629],\\\"valid\\\"],[[65630,65663],\\\"disallowed\\\"],[[65664,65786],\\\"valid\\\"],[[65787,65791],\\\"disallowed\\\"],[[65792,65794],\\\"valid\\\",[],\\\"NV8\\\"],[[65795,65798],\\\"disallowed\\\"],[[65799,65843],\\\"valid\\\",[],\\\"NV8\\\"],[[65844,65846],\\\"disallowed\\\"],[[65847,65855],\\\"valid\\\",[],\\\"NV8\\\"],[[65856,65930],\\\"valid\\\",[],\\\"NV8\\\"],[[65931,65932],\\\"valid\\\",[],\\\"NV8\\\"],[[65933,65935],\\\"disallowed\\\"],[[65936,65947],\\\"valid\\\",[],\\\"NV8\\\"],[[65948,65951],\\\"disallowed\\\"],[[65952,65952],\\\"valid\\\",[],\\\"NV8\\\"],[[65953,65999],\\\"disallowed\\\"],[[66000,66044],\\\"valid\\\",[],\\\"NV8\\\"],[[66045,66045],\\\"valid\\\"],[[66046,66175],\\\"disallowed\\\"],[[66176,66204],\\\"valid\\\"],[[66205,66207],\\\"disallowed\\\"],[[66208,66256],\\\"valid\\\"],[[66257,66271],\\\"disallowed\\\"],[[66272,66272],\\\"valid\\\"],[[66273,66299],\\\"valid\\\",[],\\\"NV8\\\"],[[66300,66303],\\\"disallowed\\\"],[[66304,66334],\\\"valid\\\"],[[66335,66335],\\\"valid\\\"],[[66336,66339],\\\"valid\\\",[],\\\"NV8\\\"],[[66340,66351],\\\"disallowed\\\"],[[66352,66368],\\\"valid\\\"],[[66369,66369],\\\"valid\\\",[],\\\"NV8\\\"],[[66370,66377],\\\"valid\\\"],[[66378,66378],\\\"valid\\\",[],\\\"NV8\\\"],[[66379,66383],\\\"disallowed\\\"],[[66384,66426],\\\"valid\\\"],[[66427,66431],\\\"disallowed\\\"],[[66432,66461],\\\"valid\\\"],[[66462,66462],\\\"disallowed\\\"],[[66463,66463],\\\"valid\\\",[],\\\"NV8\\\"],[[66464,66499],\\\"valid\\\"],[[66500,66503],\\\"disallowed\\\"],[[66504,66511],\\\"valid\\\"],[[66512,66517],\\\"valid\\\",[],\\\"NV8\\\"],[[66518,66559],\\\"disallowed\\\"],[[66560,66560],\\\"mapped\\\",[66600]],[[66561,66561],\\\"mapped\\\",[66601]],[[66562,66562],\\\"mapped\\\",[66602]],[[66563,66563],\\\"mapped\\\",[66603]],[[66564,66564],\\\"mapped\\\",[66604]],[[66565,66565],\\\"mapped\\\",[66605]],[[66566,66566],\\\"mapped\\\",[66606]],[[66567,66567],\\\"mapped\\\",[66607]],[[66568,66568],\\\"mapped\\\",[66608]],[[66569,66569],\\\"mapped\\\",[66609]],[[66570,66570],\\\"mapped\\\",[66610]],[[66571,66571],\\\"mapped\\\",[66611]],[[66572,66572],\\\"mapped\\\",[66612]],[[66573,66573],\\\"mapped\\\",[66613]],[[66574,66574],\\\"mapped\\\",[66614]],[[66575,66575],\\\"mapped\\\",[66615]],[[66576,66576],\\\"mapped\\\",[66616]],[[66577,66577],\\\"mapped\\\",[66617]],[[66578,66578],\\\"mapped\\\",[66618]],[[66579,66579],\\\"mapped\\\",[66619]],[[66580,66580],\\\"mapped\\\",[66620]],[[66581,66581],\\\"mapped\\\",[66621]],[[66582,66582],\\\"mapped\\\",[66622]],[[66583,66583],\\\"mapped\\\",[66623]],[[66584,66584],\\\"mapped\\\",[66624]],[[66585,66585],\\\"mapped\\\",[66625]],[[66586,66586],\\\"mapped\\\",[66626]],[[66587,66587],\\\"mapped\\\",[66627]],[[66588,66588],\\\"mapped\\\",[66628]],[[66589,66589],\\\"mapped\\\",[66629]],[[66590,66590],\\\"mapped\\\",[66630]],[[66591,66591],\\\"mapped\\\",[66631]],[[66592,66592],\\\"mapped\\\",[66632]],[[66593,66593],\\\"mapped\\\",[66633]],[[66594,66594],\\\"mapped\\\",[66634]],[[66595,66595],\\\"mapped\\\",[66635]],[[66596,66596],\\\"mapped\\\",[66636]],[[66597,66597],\\\"mapped\\\",[66637]],[[66598,66598],\\\"mapped\\\",[66638]],[[66599,66599],\\\"mapped\\\",[66639]],[[66600,66637],\\\"valid\\\"],[[66638,66717],\\\"valid\\\"],[[66718,66719],\\\"disallowed\\\"],[[66720,66729],\\\"valid\\\"],[[66730,66815],\\\"disallowed\\\"],[[66816,66855],\\\"valid\\\"],[[66856,66863],\\\"disallowed\\\"],[[66864,66915],\\\"valid\\\"],[[66916,66926],\\\"disallowed\\\"],[[66927,66927],\\\"valid\\\",[],\\\"NV8\\\"],[[66928,67071],\\\"disallowed\\\"],[[67072,67382],\\\"valid\\\"],[[67383,67391],\\\"disallowed\\\"],[[67392,67413],\\\"valid\\\"],[[67414,67423],\\\"disallowed\\\"],[[67424,67431],\\\"valid\\\"],[[67432,67583],\\\"disallowed\\\"],[[67584,67589],\\\"valid\\\"],[[67590,67591],\\\"disallowed\\\"],[[67592,67592],\\\"valid\\\"],[[67593,67593],\\\"disallowed\\\"],[[67594,67637],\\\"valid\\\"],[[67638,67638],\\\"disallowed\\\"],[[67639,67640],\\\"valid\\\"],[[67641,67643],\\\"disallowed\\\"],[[67644,67644],\\\"valid\\\"],[[67645,67646],\\\"disallowed\\\"],[[67647,67647],\\\"valid\\\"],[[67648,67669],\\\"valid\\\"],[[67670,67670],\\\"disallowed\\\"],[[67671,67679],\\\"valid\\\",[],\\\"NV8\\\"],[[67680,67702],\\\"valid\\\"],[[67703,67711],\\\"valid\\\",[],\\\"NV8\\\"],[[67712,67742],\\\"valid\\\"],[[67743,67750],\\\"disallowed\\\"],[[67751,67759],\\\"valid\\\",[],\\\"NV8\\\"],[[67760,67807],\\\"disallowed\\\"],[[67808,67826],\\\"valid\\\"],[[67827,67827],\\\"disallowed\\\"],[[67828,67829],\\\"valid\\\"],[[67830,67834],\\\"disallowed\\\"],[[67835,67839],\\\"valid\\\",[],\\\"NV8\\\"],[[67840,67861],\\\"valid\\\"],[[67862,67865],\\\"valid\\\",[],\\\"NV8\\\"],[[67866,67867],\\\"valid\\\",[],\\\"NV8\\\"],[[67868,67870],\\\"disallowed\\\"],[[67871,67871],\\\"valid\\\",[],\\\"NV8\\\"],[[67872,67897],\\\"valid\\\"],[[67898,67902],\\\"disallowed\\\"],[[67903,67903],\\\"valid\\\",[],\\\"NV8\\\"],[[67904,67967],\\\"disallowed\\\"],[[67968,68023],\\\"valid\\\"],[[68024,68027],\\\"disallowed\\\"],[[68028,68029],\\\"valid\\\",[],\\\"NV8\\\"],[[68030,68031],\\\"valid\\\"],[[68032,68047],\\\"valid\\\",[],\\\"NV8\\\"],[[68048,68049],\\\"disallowed\\\"],[[68050,68095],\\\"valid\\\",[],\\\"NV8\\\"],[[68096,68099],\\\"valid\\\"],[[68100,68100],\\\"disallowed\\\"],[[68101,68102],\\\"valid\\\"],[[68103,68107],\\\"disallowed\\\"],[[68108,68115],\\\"valid\\\"],[[68116,68116],\\\"disallowed\\\"],[[68117,68119],\\\"valid\\\"],[[68120,68120],\\\"disallowed\\\"],[[68121,68147],\\\"valid\\\"],[[68148,68151],\\\"disallowed\\\"],[[68152,68154],\\\"valid\\\"],[[68155,68158],\\\"disallowed\\\"],[[68159,68159],\\\"valid\\\"],[[68160,68167],\\\"valid\\\",[],\\\"NV8\\\"],[[68168,68175],\\\"disallowed\\\"],[[68176,68184],\\\"valid\\\",[],\\\"NV8\\\"],[[68185,68191],\\\"disallowed\\\"],[[68192,68220],\\\"valid\\\"],[[68221,68223],\\\"valid\\\",[],\\\"NV8\\\"],[[68224,68252],\\\"valid\\\"],[[68253,68255],\\\"valid\\\",[],\\\"NV8\\\"],[[68256,68287],\\\"disallowed\\\"],[[68288,68295],\\\"valid\\\"],[[68296,68296],\\\"valid\\\",[],\\\"NV8\\\"],[[68297,68326],\\\"valid\\\"],[[68327,68330],\\\"disallowed\\\"],[[68331,68342],\\\"valid\\\",[],\\\"NV8\\\"],[[68343,68351],\\\"disallowed\\\"],[[68352,68405],\\\"valid\\\"],[[68406,68408],\\\"disallowed\\\"],[[68409,68415],\\\"valid\\\",[],\\\"NV8\\\"],[[68416,68437],\\\"valid\\\"],[[68438,68439],\\\"disallowed\\\"],[[68440,68447],\\\"valid\\\",[],\\\"NV8\\\"],[[68448,68466],\\\"valid\\\"],[[68467,68471],\\\"disallowed\\\"],[[68472,68479],\\\"valid\\\",[],\\\"NV8\\\"],[[68480,68497],\\\"valid\\\"],[[68498,68504],\\\"disallowed\\\"],[[68505,68508],\\\"valid\\\",[],\\\"NV8\\\"],[[68509,68520],\\\"disallowed\\\"],[[68521,68527],\\\"valid\\\",[],\\\"NV8\\\"],[[68528,68607],\\\"disallowed\\\"],[[68608,68680],\\\"valid\\\"],[[68681,68735],\\\"disallowed\\\"],[[68736,68736],\\\"mapped\\\",[68800]],[[68737,68737],\\\"mapped\\\",[68801]],[[68738,68738],\\\"mapped\\\",[68802]],[[68739,68739],\\\"mapped\\\",[68803]],[[68740,68740],\\\"mapped\\\",[68804]],[[68741,68741],\\\"mapped\\\",[68805]],[[68742,68742],\\\"mapped\\\",[68806]],[[68743,68743],\\\"mapped\\\",[68807]],[[68744,68744],\\\"mapped\\\",[68808]],[[68745,68745],\\\"mapped\\\",[68809]],[[68746,68746],\\\"mapped\\\",[68810]],[[68747,68747],\\\"mapped\\\",[68811]],[[68748,68748],\\\"mapped\\\",[68812]],[[68749,68749],\\\"mapped\\\",[68813]],[[68750,68750],\\\"mapped\\\",[68814]],[[68751,68751],\\\"mapped\\\",[68815]],[[68752,68752],\\\"mapped\\\",[68816]],[[68753,68753],\\\"mapped\\\",[68817]],[[68754,68754],\\\"mapped\\\",[68818]],[[68755,68755],\\\"mapped\\\",[68819]],[[68756,68756],\\\"mapped\\\",[68820]],[[68757,68757],\\\"mapped\\\",[68821]],[[68758,68758],\\\"mapped\\\",[68822]],[[68759,68759],\\\"mapped\\\",[68823]],[[68760,68760],\\\"mapped\\\",[68824]],[[68761,68761],\\\"mapped\\\",[68825]],[[68762,68762],\\\"mapped\\\",[68826]],[[68763,68763],\\\"mapped\\\",[68827]],[[68764,68764],\\\"mapped\\\",[68828]],[[68765,68765],\\\"mapped\\\",[68829]],[[68766,68766],\\\"mapped\\\",[68830]],[[68767,68767],\\\"mapped\\\",[68831]],[[68768,68768],\\\"mapped\\\",[68832]],[[68769,68769],\\\"mapped\\\",[68833]],[[68770,68770],\\\"mapped\\\",[68834]],[[68771,68771],\\\"mapped\\\",[68835]],[[68772,68772],\\\"mapped\\\",[68836]],[[68773,68773],\\\"mapped\\\",[68837]],[[68774,68774],\\\"mapped\\\",[68838]],[[68775,68775],\\\"mapped\\\",[68839]],[[68776,68776],\\\"mapped\\\",[68840]],[[68777,68777],\\\"mapped\\\",[68841]],[[68778,68778],\\\"mapped\\\",[68842]],[[68779,68779],\\\"mapped\\\",[68843]],[[68780,68780],\\\"mapped\\\",[68844]],[[68781,68781],\\\"mapped\\\",[68845]],[[68782,68782],\\\"mapped\\\",[68846]],[[68783,68783],\\\"mapped\\\",[68847]],[[68784,68784],\\\"mapped\\\",[68848]],[[68785,68785],\\\"mapped\\\",[68849]],[[68786,68786],\\\"mapped\\\",[68850]],[[68787,68799],\\\"disallowed\\\"],[[68800,68850],\\\"valid\\\"],[[68851,68857],\\\"disallowed\\\"],[[68858,68863],\\\"valid\\\",[],\\\"NV8\\\"],[[68864,69215],\\\"disallowed\\\"],[[69216,69246],\\\"valid\\\",[],\\\"NV8\\\"],[[69247,69631],\\\"disallowed\\\"],[[69632,69702],\\\"valid\\\"],[[69703,69709],\\\"valid\\\",[],\\\"NV8\\\"],[[69710,69713],\\\"disallowed\\\"],[[69714,69733],\\\"valid\\\",[],\\\"NV8\\\"],[[69734,69743],\\\"valid\\\"],[[69744,69758],\\\"disallowed\\\"],[[69759,69759],\\\"valid\\\"],[[69760,69818],\\\"valid\\\"],[[69819,69820],\\\"valid\\\",[],\\\"NV8\\\"],[[69821,69821],\\\"disallowed\\\"],[[69822,69825],\\\"valid\\\",[],\\\"NV8\\\"],[[69826,69839],\\\"disallowed\\\"],[[69840,69864],\\\"valid\\\"],[[69865,69871],\\\"disallowed\\\"],[[69872,69881],\\\"valid\\\"],[[69882,69887],\\\"disallowed\\\"],[[69888,69940],\\\"valid\\\"],[[69941,69941],\\\"disallowed\\\"],[[69942,69951],\\\"valid\\\"],[[69952,69955],\\\"valid\\\",[],\\\"NV8\\\"],[[69956,69967],\\\"disallowed\\\"],[[69968,70003],\\\"valid\\\"],[[70004,70005],\\\"valid\\\",[],\\\"NV8\\\"],[[70006,70006],\\\"valid\\\"],[[70007,70015],\\\"disallowed\\\"],[[70016,70084],\\\"valid\\\"],[[70085,70088],\\\"valid\\\",[],\\\"NV8\\\"],[[70089,70089],\\\"valid\\\",[],\\\"NV8\\\"],[[70090,70092],\\\"valid\\\"],[[70093,70093],\\\"valid\\\",[],\\\"NV8\\\"],[[70094,70095],\\\"disallowed\\\"],[[70096,70105],\\\"valid\\\"],[[70106,70106],\\\"valid\\\"],[[70107,70107],\\\"valid\\\",[],\\\"NV8\\\"],[[70108,70108],\\\"valid\\\"],[[70109,70111],\\\"valid\\\",[],\\\"NV8\\\"],[[70112,70112],\\\"disallowed\\\"],[[70113,70132],\\\"valid\\\",[],\\\"NV8\\\"],[[70133,70143],\\\"disallowed\\\"],[[70144,70161],\\\"valid\\\"],[[70162,70162],\\\"disallowed\\\"],[[70163,70199],\\\"valid\\\"],[[70200,70205],\\\"valid\\\",[],\\\"NV8\\\"],[[70206,70271],\\\"disallowed\\\"],[[70272,70278],\\\"valid\\\"],[[70279,70279],\\\"disallowed\\\"],[[70280,70280],\\\"valid\\\"],[[70281,70281],\\\"disallowed\\\"],[[70282,70285],\\\"valid\\\"],[[70286,70286],\\\"disallowed\\\"],[[70287,70301],\\\"valid\\\"],[[70302,70302],\\\"disallowed\\\"],[[70303,70312],\\\"valid\\\"],[[70313,70313],\\\"valid\\\",[],\\\"NV8\\\"],[[70314,70319],\\\"disallowed\\\"],[[70320,70378],\\\"valid\\\"],[[70379,70383],\\\"disallowed\\\"],[[70384,70393],\\\"valid\\\"],[[70394,70399],\\\"disallowed\\\"],[[70400,70400],\\\"valid\\\"],[[70401,70403],\\\"valid\\\"],[[70404,70404],\\\"disallowed\\\"],[[70405,70412],\\\"valid\\\"],[[70413,70414],\\\"disallowed\\\"],[[70415,70416],\\\"valid\\\"],[[70417,70418],\\\"disallowed\\\"],[[70419,70440],\\\"valid\\\"],[[70441,70441],\\\"disallowed\\\"],[[70442,70448],\\\"valid\\\"],[[70449,70449],\\\"disallowed\\\"],[[70450,70451],\\\"valid\\\"],[[70452,70452],\\\"disallowed\\\"],[[70453,70457],\\\"valid\\\"],[[70458,70459],\\\"disallowed\\\"],[[70460,70468],\\\"valid\\\"],[[70469,70470],\\\"disallowed\\\"],[[70471,70472],\\\"valid\\\"],[[70473,70474],\\\"disallowed\\\"],[[70475,70477],\\\"valid\\\"],[[70478,70479],\\\"disallowed\\\"],[[70480,70480],\\\"valid\\\"],[[70481,70486],\\\"disallowed\\\"],[[70487,70487],\\\"valid\\\"],[[70488,70492],\\\"disallowed\\\"],[[70493,70499],\\\"valid\\\"],[[70500,70501],\\\"disallowed\\\"],[[70502,70508],\\\"valid\\\"],[[70509,70511],\\\"disallowed\\\"],[[70512,70516],\\\"valid\\\"],[[70517,70783],\\\"disallowed\\\"],[[70784,70853],\\\"valid\\\"],[[70854,70854],\\\"valid\\\",[],\\\"NV8\\\"],[[70855,70855],\\\"valid\\\"],[[70856,70863],\\\"disallowed\\\"],[[70864,70873],\\\"valid\\\"],[[70874,71039],\\\"disallowed\\\"],[[71040,71093],\\\"valid\\\"],[[71094,71095],\\\"disallowed\\\"],[[71096,71104],\\\"valid\\\"],[[71105,71113],\\\"valid\\\",[],\\\"NV8\\\"],[[71114,71127],\\\"valid\\\",[],\\\"NV8\\\"],[[71128,71133],\\\"valid\\\"],[[71134,71167],\\\"disallowed\\\"],[[71168,71232],\\\"valid\\\"],[[71233,71235],\\\"valid\\\",[],\\\"NV8\\\"],[[71236,71236],\\\"valid\\\"],[[71237,71247],\\\"disallowed\\\"],[[71248,71257],\\\"valid\\\"],[[71258,71295],\\\"disallowed\\\"],[[71296,71351],\\\"valid\\\"],[[71352,71359],\\\"disallowed\\\"],[[71360,71369],\\\"valid\\\"],[[71370,71423],\\\"disallowed\\\"],[[71424,71449],\\\"valid\\\"],[[71450,71452],\\\"disallowed\\\"],[[71453,71467],\\\"valid\\\"],[[71468,71471],\\\"disallowed\\\"],[[71472,71481],\\\"valid\\\"],[[71482,71487],\\\"valid\\\",[],\\\"NV8\\\"],[[71488,71839],\\\"disallowed\\\"],[[71840,71840],\\\"mapped\\\",[71872]],[[71841,71841],\\\"mapped\\\",[71873]],[[71842,71842],\\\"mapped\\\",[71874]],[[71843,71843],\\\"mapped\\\",[71875]],[[71844,71844],\\\"mapped\\\",[71876]],[[71845,71845],\\\"mapped\\\",[71877]],[[71846,71846],\\\"mapped\\\",[71878]],[[71847,71847],\\\"mapped\\\",[71879]],[[71848,71848],\\\"mapped\\\",[71880]],[[71849,71849],\\\"mapped\\\",[71881]],[[71850,71850],\\\"mapped\\\",[71882]],[[71851,71851],\\\"mapped\\\",[71883]],[[71852,71852],\\\"mapped\\\",[71884]],[[71853,71853],\\\"mapped\\\",[71885]],[[71854,71854],\\\"mapped\\\",[71886]],[[71855,71855],\\\"mapped\\\",[71887]],[[71856,71856],\\\"mapped\\\",[71888]],[[71857,71857],\\\"mapped\\\",[71889]],[[71858,71858],\\\"mapped\\\",[71890]],[[71859,71859],\\\"mapped\\\",[71891]],[[71860,71860],\\\"mapped\\\",[71892]],[[71861,71861],\\\"mapped\\\",[71893]],[[71862,71862],\\\"mapped\\\",[71894]],[[71863,71863],\\\"mapped\\\",[71895]],[[71864,71864],\\\"mapped\\\",[71896]],[[71865,71865],\\\"mapped\\\",[71897]],[[71866,71866],\\\"mapped\\\",[71898]],[[71867,71867],\\\"mapped\\\",[71899]],[[71868,71868],\\\"mapped\\\",[71900]],[[71869,71869],\\\"mapped\\\",[71901]],[[71870,71870],\\\"mapped\\\",[71902]],[[71871,71871],\\\"mapped\\\",[71903]],[[71872,71913],\\\"valid\\\"],[[71914,71922],\\\"valid\\\",[],\\\"NV8\\\"],[[71923,71934],\\\"disallowed\\\"],[[71935,71935],\\\"valid\\\"],[[71936,72383],\\\"disallowed\\\"],[[72384,72440],\\\"valid\\\"],[[72441,73727],\\\"disallowed\\\"],[[73728,74606],\\\"valid\\\"],[[74607,74648],\\\"valid\\\"],[[74649,74649],\\\"valid\\\"],[[74650,74751],\\\"disallowed\\\"],[[74752,74850],\\\"valid\\\",[],\\\"NV8\\\"],[[74851,74862],\\\"valid\\\",[],\\\"NV8\\\"],[[74863,74863],\\\"disallowed\\\"],[[74864,74867],\\\"valid\\\",[],\\\"NV8\\\"],[[74868,74868],\\\"valid\\\",[],\\\"NV8\\\"],[[74869,74879],\\\"disallowed\\\"],[[74880,75075],\\\"valid\\\"],[[75076,77823],\\\"disallowed\\\"],[[77824,78894],\\\"valid\\\"],[[78895,82943],\\\"disallowed\\\"],[[82944,83526],\\\"valid\\\"],[[83527,92159],\\\"disallowed\\\"],[[92160,92728],\\\"valid\\\"],[[92729,92735],\\\"disallowed\\\"],[[92736,92766],\\\"valid\\\"],[[92767,92767],\\\"disallowed\\\"],[[92768,92777],\\\"valid\\\"],[[92778,92781],\\\"disallowed\\\"],[[92782,92783],\\\"valid\\\",[],\\\"NV8\\\"],[[92784,92879],\\\"disallowed\\\"],[[92880,92909],\\\"valid\\\"],[[92910,92911],\\\"disallowed\\\"],[[92912,92916],\\\"valid\\\"],[[92917,92917],\\\"valid\\\",[],\\\"NV8\\\"],[[92918,92927],\\\"disallowed\\\"],[[92928,92982],\\\"valid\\\"],[[92983,92991],\\\"valid\\\",[],\\\"NV8\\\"],[[92992,92995],\\\"valid\\\"],[[92996,92997],\\\"valid\\\",[],\\\"NV8\\\"],[[92998,93007],\\\"disallowed\\\"],[[93008,93017],\\\"valid\\\"],[[93018,93018],\\\"disallowed\\\"],[[93019,93025],\\\"valid\\\",[],\\\"NV8\\\"],[[93026,93026],\\\"disallowed\\\"],[[93027,93047],\\\"valid\\\"],[[93048,93052],\\\"disallowed\\\"],[[93053,93071],\\\"valid\\\"],[[93072,93951],\\\"disallowed\\\"],[[93952,94020],\\\"valid\\\"],[[94021,94031],\\\"disallowed\\\"],[[94032,94078],\\\"valid\\\"],[[94079,94094],\\\"disallowed\\\"],[[94095,94111],\\\"valid\\\"],[[94112,110591],\\\"disallowed\\\"],[[110592,110593],\\\"valid\\\"],[[110594,113663],\\\"disallowed\\\"],[[113664,113770],\\\"valid\\\"],[[113771,113775],\\\"disallowed\\\"],[[113776,113788],\\\"valid\\\"],[[113789,113791],\\\"disallowed\\\"],[[113792,113800],\\\"valid\\\"],[[113801,113807],\\\"disallowed\\\"],[[113808,113817],\\\"valid\\\"],[[113818,113819],\\\"disallowed\\\"],[[113820,113820],\\\"valid\\\",[],\\\"NV8\\\"],[[113821,113822],\\\"valid\\\"],[[113823,113823],\\\"valid\\\",[],\\\"NV8\\\"],[[113824,113827],\\\"ignored\\\"],[[113828,118783],\\\"disallowed\\\"],[[118784,119029],\\\"valid\\\",[],\\\"NV8\\\"],[[119030,119039],\\\"disallowed\\\"],[[119040,119078],\\\"valid\\\",[],\\\"NV8\\\"],[[119079,119080],\\\"disallowed\\\"],[[119081,119081],\\\"valid\\\",[],\\\"NV8\\\"],[[119082,119133],\\\"valid\\\",[],\\\"NV8\\\"],[[119134,119134],\\\"mapped\\\",[119127,119141]],[[119135,119135],\\\"mapped\\\",[119128,119141]],[[119136,119136],\\\"mapped\\\",[119128,119141,119150]],[[119137,119137],\\\"mapped\\\",[119128,119141,119151]],[[119138,119138],\\\"mapped\\\",[119128,119141,119152]],[[119139,119139],\\\"mapped\\\",[119128,119141,119153]],[[119140,119140],\\\"mapped\\\",[119128,119141,119154]],[[119141,119154],\\\"valid\\\",[],\\\"NV8\\\"],[[119155,119162],\\\"disallowed\\\"],[[119163,119226],\\\"valid\\\",[],\\\"NV8\\\"],[[119227,119227],\\\"mapped\\\",[119225,119141]],[[119228,119228],\\\"mapped\\\",[119226,119141]],[[119229,119229],\\\"mapped\\\",[119225,119141,119150]],[[119230,119230],\\\"mapped\\\",[119226,119141,119150]],[[119231,119231],\\\"mapped\\\",[119225,119141,119151]],[[119232,119232],\\\"mapped\\\",[119226,119141,119151]],[[119233,119261],\\\"valid\\\",[],\\\"NV8\\\"],[[119262,119272],\\\"valid\\\",[],\\\"NV8\\\"],[[119273,119295],\\\"disallowed\\\"],[[119296,119365],\\\"valid\\\",[],\\\"NV8\\\"],[[119366,119551],\\\"disallowed\\\"],[[119552,119638],\\\"valid\\\",[],\\\"NV8\\\"],[[119639,119647],\\\"disallowed\\\"],[[119648,119665],\\\"valid\\\",[],\\\"NV8\\\"],[[119666,119807],\\\"disallowed\\\"],[[119808,119808],\\\"mapped\\\",[97]],[[119809,119809],\\\"mapped\\\",[98]],[[119810,119810],\\\"mapped\\\",[99]],[[119811,119811],\\\"mapped\\\",[100]],[[119812,119812],\\\"mapped\\\",[101]],[[119813,119813],\\\"mapped\\\",[102]],[[119814,119814],\\\"mapped\\\",[103]],[[119815,119815],\\\"mapped\\\",[104]],[[119816,119816],\\\"mapped\\\",[105]],[[119817,119817],\\\"mapped\\\",[106]],[[119818,119818],\\\"mapped\\\",[107]],[[119819,119819],\\\"mapped\\\",[108]],[[119820,119820],\\\"mapped\\\",[109]],[[119821,119821],\\\"mapped\\\",[110]],[[119822,119822],\\\"mapped\\\",[111]],[[119823,119823],\\\"mapped\\\",[112]],[[119824,119824],\\\"mapped\\\",[113]],[[119825,119825],\\\"mapped\\\",[114]],[[119826,119826],\\\"mapped\\\",[115]],[[119827,119827],\\\"mapped\\\",[116]],[[119828,119828],\\\"mapped\\\",[117]],[[119829,119829],\\\"mapped\\\",[118]],[[119830,119830],\\\"mapped\\\",[119]],[[119831,119831],\\\"mapped\\\",[120]],[[119832,119832],\\\"mapped\\\",[121]],[[119833,119833],\\\"mapped\\\",[122]],[[119834,119834],\\\"mapped\\\",[97]],[[119835,119835],\\\"mapped\\\",[98]],[[119836,119836],\\\"mapped\\\",[99]],[[119837,119837],\\\"mapped\\\",[100]],[[119838,119838],\\\"mapped\\\",[101]],[[119839,119839],\\\"mapped\\\",[102]],[[119840,119840],\\\"mapped\\\",[103]],[[119841,119841],\\\"mapped\\\",[104]],[[119842,119842],\\\"mapped\\\",[105]],[[119843,119843],\\\"mapped\\\",[106]],[[119844,119844],\\\"mapped\\\",[107]],[[119845,119845],\\\"mapped\\\",[108]],[[119846,119846],\\\"mapped\\\",[109]],[[119847,119847],\\\"mapped\\\",[110]],[[119848,119848],\\\"mapped\\\",[111]],[[119849,119849],\\\"mapped\\\",[112]],[[119850,119850],\\\"mapped\\\",[113]],[[119851,119851],\\\"mapped\\\",[114]],[[119852,119852],\\\"mapped\\\",[115]],[[119853,119853],\\\"mapped\\\",[116]],[[119854,119854],\\\"mapped\\\",[117]],[[119855,119855],\\\"mapped\\\",[118]],[[119856,119856],\\\"mapped\\\",[119]],[[119857,119857],\\\"mapped\\\",[120]],[[119858,119858],\\\"mapped\\\",[121]],[[119859,119859],\\\"mapped\\\",[122]],[[119860,119860],\\\"mapped\\\",[97]],[[119861,119861],\\\"mapped\\\",[98]],[[119862,119862],\\\"mapped\\\",[99]],[[119863,119863],\\\"mapped\\\",[100]],[[119864,119864],\\\"mapped\\\",[101]],[[119865,119865],\\\"mapped\\\",[102]],[[119866,119866],\\\"mapped\\\",[103]],[[119867,119867],\\\"mapped\\\",[104]],[[119868,119868],\\\"mapped\\\",[105]],[[119869,119869],\\\"mapped\\\",[106]],[[119870,119870],\\\"mapped\\\",[107]],[[119871,119871],\\\"mapped\\\",[108]],[[119872,119872],\\\"mapped\\\",[109]],[[119873,119873],\\\"mapped\\\",[110]],[[119874,119874],\\\"mapped\\\",[111]],[[119875,119875],\\\"mapped\\\",[112]],[[119876,119876],\\\"mapped\\\",[113]],[[119877,119877],\\\"mapped\\\",[114]],[[119878,119878],\\\"mapped\\\",[115]],[[119879,119879],\\\"mapped\\\",[116]],[[119880,119880],\\\"mapped\\\",[117]],[[119881,119881],\\\"mapped\\\",[118]],[[119882,119882],\\\"mapped\\\",[119]],[[119883,119883],\\\"mapped\\\",[120]],[[119884,119884],\\\"mapped\\\",[121]],[[119885,119885],\\\"mapped\\\",[122]],[[119886,119886],\\\"mapped\\\",[97]],[[119887,119887],\\\"mapped\\\",[98]],[[119888,119888],\\\"mapped\\\",[99]],[[119889,119889],\\\"mapped\\\",[100]],[[119890,119890],\\\"mapped\\\",[101]],[[119891,119891],\\\"mapped\\\",[102]],[[119892,119892],\\\"mapped\\\",[103]],[[119893,119893],\\\"disallowed\\\"],[[119894,119894],\\\"mapped\\\",[105]],[[119895,119895],\\\"mapped\\\",[106]],[[119896,119896],\\\"mapped\\\",[107]],[[119897,119897],\\\"mapped\\\",[108]],[[119898,119898],\\\"mapped\\\",[109]],[[119899,119899],\\\"mapped\\\",[110]],[[119900,119900],\\\"mapped\\\",[111]],[[119901,119901],\\\"mapped\\\",[112]],[[119902,119902],\\\"mapped\\\",[113]],[[119903,119903],\\\"mapped\\\",[114]],[[119904,119904],\\\"mapped\\\",[115]],[[119905,119905],\\\"mapped\\\",[116]],[[119906,119906],\\\"mapped\\\",[117]],[[119907,119907],\\\"mapped\\\",[118]],[[119908,119908],\\\"mapped\\\",[119]],[[119909,119909],\\\"mapped\\\",[120]],[[119910,119910],\\\"mapped\\\",[121]],[[119911,119911],\\\"mapped\\\",[122]],[[119912,119912],\\\"mapped\\\",[97]],[[119913,119913],\\\"mapped\\\",[98]],[[119914,119914],\\\"mapped\\\",[99]],[[119915,119915],\\\"mapped\\\",[100]],[[119916,119916],\\\"mapped\\\",[101]],[[119917,119917],\\\"mapped\\\",[102]],[[119918,119918],\\\"mapped\\\",[103]],[[119919,119919],\\\"mapped\\\",[104]],[[119920,119920],\\\"mapped\\\",[105]],[[119921,119921],\\\"mapped\\\",[106]],[[119922,119922],\\\"mapped\\\",[107]],[[119923,119923],\\\"mapped\\\",[108]],[[119924,119924],\\\"mapped\\\",[109]],[[119925,119925],\\\"mapped\\\",[110]],[[119926,119926],\\\"mapped\\\",[111]],[[119927,119927],\\\"mapped\\\",[112]],[[119928,119928],\\\"mapped\\\",[113]],[[119929,119929],\\\"mapped\\\",[114]],[[119930,119930],\\\"mapped\\\",[115]],[[119931,119931],\\\"mapped\\\",[116]],[[119932,119932],\\\"mapped\\\",[117]],[[119933,119933],\\\"mapped\\\",[118]],[[119934,119934],\\\"mapped\\\",[119]],[[119935,119935],\\\"mapped\\\",[120]],[[119936,119936],\\\"mapped\\\",[121]],[[119937,119937],\\\"mapped\\\",[122]],[[119938,119938],\\\"mapped\\\",[97]],[[119939,119939],\\\"mapped\\\",[98]],[[119940,119940],\\\"mapped\\\",[99]],[[119941,119941],\\\"mapped\\\",[100]],[[119942,119942],\\\"mapped\\\",[101]],[[119943,119943],\\\"mapped\\\",[102]],[[119944,119944],\\\"mapped\\\",[103]],[[119945,119945],\\\"mapped\\\",[104]],[[119946,119946],\\\"mapped\\\",[105]],[[119947,119947],\\\"mapped\\\",[106]],[[119948,119948],\\\"mapped\\\",[107]],[[119949,119949],\\\"mapped\\\",[108]],[[119950,119950],\\\"mapped\\\",[109]],[[119951,119951],\\\"mapped\\\",[110]],[[119952,119952],\\\"mapped\\\",[111]],[[119953,119953],\\\"mapped\\\",[112]],[[119954,119954],\\\"mapped\\\",[113]],[[119955,119955],\\\"mapped\\\",[114]],[[119956,119956],\\\"mapped\\\",[115]],[[119957,119957],\\\"mapped\\\",[116]],[[119958,119958],\\\"mapped\\\",[117]],[[119959,119959],\\\"mapped\\\",[118]],[[119960,119960],\\\"mapped\\\",[119]],[[119961,119961],\\\"mapped\\\",[120]],[[119962,119962],\\\"mapped\\\",[121]],[[119963,119963],\\\"mapped\\\",[122]],[[119964,119964],\\\"mapped\\\",[97]],[[119965,119965],\\\"disallowed\\\"],[[119966,119966],\\\"mapped\\\",[99]],[[119967,119967],\\\"mapped\\\",[100]],[[119968,119969],\\\"disallowed\\\"],[[119970,119970],\\\"mapped\\\",[103]],[[119971,119972],\\\"disallowed\\\"],[[119973,119973],\\\"mapped\\\",[106]],[[119974,119974],\\\"mapped\\\",[107]],[[119975,119976],\\\"disallowed\\\"],[[119977,119977],\\\"mapped\\\",[110]],[[119978,119978],\\\"mapped\\\",[111]],[[119979,119979],\\\"mapped\\\",[112]],[[119980,119980],\\\"mapped\\\",[113]],[[119981,119981],\\\"disallowed\\\"],[[119982,119982],\\\"mapped\\\",[115]],[[119983,119983],\\\"mapped\\\",[116]],[[119984,119984],\\\"mapped\\\",[117]],[[119985,119985],\\\"mapped\\\",[118]],[[119986,119986],\\\"mapped\\\",[119]],[[119987,119987],\\\"mapped\\\",[120]],[[119988,119988],\\\"mapped\\\",[121]],[[119989,119989],\\\"mapped\\\",[122]],[[119990,119990],\\\"mapped\\\",[97]],[[119991,119991],\\\"mapped\\\",[98]],[[119992,119992],\\\"mapped\\\",[99]],[[119993,119993],\\\"mapped\\\",[100]],[[119994,119994],\\\"disallowed\\\"],[[119995,119995],\\\"mapped\\\",[102]],[[119996,119996],\\\"disallowed\\\"],[[119997,119997],\\\"mapped\\\",[104]],[[119998,119998],\\\"mapped\\\",[105]],[[119999,119999],\\\"mapped\\\",[106]],[[120000,120000],\\\"mapped\\\",[107]],[[120001,120001],\\\"mapped\\\",[108]],[[120002,120002],\\\"mapped\\\",[109]],[[120003,120003],\\\"mapped\\\",[110]],[[120004,120004],\\\"disallowed\\\"],[[120005,120005],\\\"mapped\\\",[112]],[[120006,120006],\\\"mapped\\\",[113]],[[120007,120007],\\\"mapped\\\",[114]],[[120008,120008],\\\"mapped\\\",[115]],[[120009,120009],\\\"mapped\\\",[116]],[[120010,120010],\\\"mapped\\\",[117]],[[120011,120011],\\\"mapped\\\",[118]],[[120012,120012],\\\"mapped\\\",[119]],[[120013,120013],\\\"mapped\\\",[120]],[[120014,120014],\\\"mapped\\\",[121]],[[120015,120015],\\\"mapped\\\",[122]],[[120016,120016],\\\"mapped\\\",[97]],[[120017,120017],\\\"mapped\\\",[98]],[[120018,120018],\\\"mapped\\\",[99]],[[120019,120019],\\\"mapped\\\",[100]],[[120020,120020],\\\"mapped\\\",[101]],[[120021,120021],\\\"mapped\\\",[102]],[[120022,120022],\\\"mapped\\\",[103]],[[120023,120023],\\\"mapped\\\",[104]],[[120024,120024],\\\"mapped\\\",[105]],[[120025,120025],\\\"mapped\\\",[106]],[[120026,120026],\\\"mapped\\\",[107]],[[120027,120027],\\\"mapped\\\",[108]],[[120028,120028],\\\"mapped\\\",[109]],[[120029,120029],\\\"mapped\\\",[110]],[[120030,120030],\\\"mapped\\\",[111]],[[120031,120031],\\\"mapped\\\",[112]],[[120032,120032],\\\"mapped\\\",[113]],[[120033,120033],\\\"mapped\\\",[114]],[[120034,120034],\\\"mapped\\\",[115]],[[120035,120035],\\\"mapped\\\",[116]],[[120036,120036],\\\"mapped\\\",[117]],[[120037,120037],\\\"mapped\\\",[118]],[[120038,120038],\\\"mapped\\\",[119]],[[120039,120039],\\\"mapped\\\",[120]],[[120040,120040],\\\"mapped\\\",[121]],[[120041,120041],\\\"mapped\\\",[122]],[[120042,120042],\\\"mapped\\\",[97]],[[120043,120043],\\\"mapped\\\",[98]],[[120044,120044],\\\"mapped\\\",[99]],[[120045,120045],\\\"mapped\\\",[100]],[[120046,120046],\\\"mapped\\\",[101]],[[120047,120047],\\\"mapped\\\",[102]],[[120048,120048],\\\"mapped\\\",[103]],[[120049,120049],\\\"mapped\\\",[104]],[[120050,120050],\\\"mapped\\\",[105]],[[120051,120051],\\\"mapped\\\",[106]],[[120052,120052],\\\"mapped\\\",[107]],[[120053,120053],\\\"mapped\\\",[108]],[[120054,120054],\\\"mapped\\\",[109]],[[120055,120055],\\\"mapped\\\",[110]],[[120056,120056],\\\"mapped\\\",[111]],[[120057,120057],\\\"mapped\\\",[112]],[[120058,120058],\\\"mapped\\\",[113]],[[120059,120059],\\\"mapped\\\",[114]],[[120060,120060],\\\"mapped\\\",[115]],[[120061,120061],\\\"mapped\\\",[116]],[[120062,120062],\\\"mapped\\\",[117]],[[120063,120063],\\\"mapped\\\",[118]],[[120064,120064],\\\"mapped\\\",[119]],[[120065,120065],\\\"mapped\\\",[120]],[[120066,120066],\\\"mapped\\\",[121]],[[120067,120067],\\\"mapped\\\",[122]],[[120068,120068],\\\"mapped\\\",[97]],[[120069,120069],\\\"mapped\\\",[98]],[[120070,120070],\\\"disallowed\\\"],[[120071,120071],\\\"mapped\\\",[100]],[[120072,120072],\\\"mapped\\\",[101]],[[120073,120073],\\\"mapped\\\",[102]],[[120074,120074],\\\"mapped\\\",[103]],[[120075,120076],\\\"disallowed\\\"],[[120077,120077],\\\"mapped\\\",[106]],[[120078,120078],\\\"mapped\\\",[107]],[[120079,120079],\\\"mapped\\\",[108]],[[120080,120080],\\\"mapped\\\",[109]],[[120081,120081],\\\"mapped\\\",[110]],[[120082,120082],\\\"mapped\\\",[111]],[[120083,120083],\\\"mapped\\\",[112]],[[120084,120084],\\\"mapped\\\",[113]],[[120085,120085],\\\"disallowed\\\"],[[120086,120086],\\\"mapped\\\",[115]],[[120087,120087],\\\"mapped\\\",[116]],[[120088,120088],\\\"mapped\\\",[117]],[[120089,120089],\\\"mapped\\\",[118]],[[120090,120090],\\\"mapped\\\",[119]],[[120091,120091],\\\"mapped\\\",[120]],[[120092,120092],\\\"mapped\\\",[121]],[[120093,120093],\\\"disallowed\\\"],[[120094,120094],\\\"mapped\\\",[97]],[[120095,120095],\\\"mapped\\\",[98]],[[120096,120096],\\\"mapped\\\",[99]],[[120097,120097],\\\"mapped\\\",[100]],[[120098,120098],\\\"mapped\\\",[101]],[[120099,120099],\\\"mapped\\\",[102]],[[120100,120100],\\\"mapped\\\",[103]],[[120101,120101],\\\"mapped\\\",[104]],[[120102,120102],\\\"mapped\\\",[105]],[[120103,120103],\\\"mapped\\\",[106]],[[120104,120104],\\\"mapped\\\",[107]],[[120105,120105],\\\"mapped\\\",[108]],[[120106,120106],\\\"mapped\\\",[109]],[[120107,120107],\\\"mapped\\\",[110]],[[120108,120108],\\\"mapped\\\",[111]],[[120109,120109],\\\"mapped\\\",[112]],[[120110,120110],\\\"mapped\\\",[113]],[[120111,120111],\\\"mapped\\\",[114]],[[120112,120112],\\\"mapped\\\",[115]],[[120113,120113],\\\"mapped\\\",[116]],[[120114,120114],\\\"mapped\\\",[117]],[[120115,120115],\\\"mapped\\\",[118]],[[120116,120116],\\\"mapped\\\",[119]],[[120117,120117],\\\"mapped\\\",[120]],[[120118,120118],\\\"mapped\\\",[121]],[[120119,120119],\\\"mapped\\\",[122]],[[120120,120120],\\\"mapped\\\",[97]],[[120121,120121],\\\"mapped\\\",[98]],[[120122,120122],\\\"disallowed\\\"],[[120123,120123],\\\"mapped\\\",[100]],[[120124,120124],\\\"mapped\\\",[101]],[[120125,120125],\\\"mapped\\\",[102]],[[120126,120126],\\\"mapped\\\",[103]],[[120127,120127],\\\"disallowed\\\"],[[120128,120128],\\\"mapped\\\",[105]],[[120129,120129],\\\"mapped\\\",[106]],[[120130,120130],\\\"mapped\\\",[107]],[[120131,120131],\\\"mapped\\\",[108]],[[120132,120132],\\\"mapped\\\",[109]],[[120133,120133],\\\"disallowed\\\"],[[120134,120134],\\\"mapped\\\",[111]],[[120135,120137],\\\"disallowed\\\"],[[120138,120138],\\\"mapped\\\",[115]],[[120139,120139],\\\"mapped\\\",[116]],[[120140,120140],\\\"mapped\\\",[117]],[[120141,120141],\\\"mapped\\\",[118]],[[120142,120142],\\\"mapped\\\",[119]],[[120143,120143],\\\"mapped\\\",[120]],[[120144,120144],\\\"mapped\\\",[121]],[[120145,120145],\\\"disallowed\\\"],[[120146,120146],\\\"mapped\\\",[97]],[[120147,120147],\\\"mapped\\\",[98]],[[120148,120148],\\\"mapped\\\",[99]],[[120149,120149],\\\"mapped\\\",[100]],[[120150,120150],\\\"mapped\\\",[101]],[[120151,120151],\\\"mapped\\\",[102]],[[120152,120152],\\\"mapped\\\",[103]],[[120153,120153],\\\"mapped\\\",[104]],[[120154,120154],\\\"mapped\\\",[105]],[[120155,120155],\\\"mapped\\\",[106]],[[120156,120156],\\\"mapped\\\",[107]],[[120157,120157],\\\"mapped\\\",[108]],[[120158,120158],\\\"mapped\\\",[109]],[[120159,120159],\\\"mapped\\\",[110]],[[120160,120160],\\\"mapped\\\",[111]],[[120161,120161],\\\"mapped\\\",[112]],[[120162,120162],\\\"mapped\\\",[113]],[[120163,120163],\\\"mapped\\\",[114]],[[120164,120164],\\\"mapped\\\",[115]],[[120165,120165],\\\"mapped\\\",[116]],[[120166,120166],\\\"mapped\\\",[117]],[[120167,120167],\\\"mapped\\\",[118]],[[120168,120168],\\\"mapped\\\",[119]],[[120169,120169],\\\"mapped\\\",[120]],[[120170,120170],\\\"mapped\\\",[121]],[[120171,120171],\\\"mapped\\\",[122]],[[120172,120172],\\\"mapped\\\",[97]],[[120173,120173],\\\"mapped\\\",[98]],[[120174,120174],\\\"mapped\\\",[99]],[[120175,120175],\\\"mapped\\\",[100]],[[120176,120176],\\\"mapped\\\",[101]],[[120177,120177],\\\"mapped\\\",[102]],[[120178,120178],\\\"mapped\\\",[103]],[[120179,120179],\\\"mapped\\\",[104]],[[120180,120180],\\\"mapped\\\",[105]],[[120181,120181],\\\"mapped\\\",[106]],[[120182,120182],\\\"mapped\\\",[107]],[[120183,120183],\\\"mapped\\\",[108]],[[120184,120184],\\\"mapped\\\",[109]],[[120185,120185],\\\"mapped\\\",[110]],[[120186,120186],\\\"mapped\\\",[111]],[[120187,120187],\\\"mapped\\\",[112]],[[120188,120188],\\\"mapped\\\",[113]],[[120189,120189],\\\"mapped\\\",[114]],[[120190,120190],\\\"mapped\\\",[115]],[[120191,120191],\\\"mapped\\\",[116]],[[120192,120192],\\\"mapped\\\",[117]],[[120193,120193],\\\"mapped\\\",[118]],[[120194,120194],\\\"mapped\\\",[119]],[[120195,120195],\\\"mapped\\\",[120]],[[120196,120196],\\\"mapped\\\",[121]],[[120197,120197],\\\"mapped\\\",[122]],[[120198,120198],\\\"mapped\\\",[97]],[[120199,120199],\\\"mapped\\\",[98]],[[120200,120200],\\\"mapped\\\",[99]],[[120201,120201],\\\"mapped\\\",[100]],[[120202,120202],\\\"mapped\\\",[101]],[[120203,120203],\\\"mapped\\\",[102]],[[120204,120204],\\\"mapped\\\",[103]],[[120205,120205],\\\"mapped\\\",[104]],[[120206,120206],\\\"mapped\\\",[105]],[[120207,120207],\\\"mapped\\\",[106]],[[120208,120208],\\\"mapped\\\",[107]],[[120209,120209],\\\"mapped\\\",[108]],[[120210,120210],\\\"mapped\\\",[109]],[[120211,120211],\\\"mapped\\\",[110]],[[120212,120212],\\\"mapped\\\",[111]],[[120213,120213],\\\"mapped\\\",[112]],[[120214,120214],\\\"mapped\\\",[113]],[[120215,120215],\\\"mapped\\\",[114]],[[120216,120216],\\\"mapped\\\",[115]],[[120217,120217],\\\"mapped\\\",[116]],[[120218,120218],\\\"mapped\\\",[117]],[[120219,120219],\\\"mapped\\\",[118]],[[120220,120220],\\\"mapped\\\",[119]],[[120221,120221],\\\"mapped\\\",[120]],[[120222,120222],\\\"mapped\\\",[121]],[[120223,120223],\\\"mapped\\\",[122]],[[120224,120224],\\\"mapped\\\",[97]],[[120225,120225],\\\"mapped\\\",[98]],[[120226,120226],\\\"mapped\\\",[99]],[[120227,120227],\\\"mapped\\\",[100]],[[120228,120228],\\\"mapped\\\",[101]],[[120229,120229],\\\"mapped\\\",[102]],[[120230,120230],\\\"mapped\\\",[103]],[[120231,120231],\\\"mapped\\\",[104]],[[120232,120232],\\\"mapped\\\",[105]],[[120233,120233],\\\"mapped\\\",[106]],[[120234,120234],\\\"mapped\\\",[107]],[[120235,120235],\\\"mapped\\\",[108]],[[120236,120236],\\\"mapped\\\",[109]],[[120237,120237],\\\"mapped\\\",[110]],[[120238,120238],\\\"mapped\\\",[111]],[[120239,120239],\\\"mapped\\\",[112]],[[120240,120240],\\\"mapped\\\",[113]],[[120241,120241],\\\"mapped\\\",[114]],[[120242,120242],\\\"mapped\\\",[115]],[[120243,120243],\\\"mapped\\\",[116]],[[120244,120244],\\\"mapped\\\",[117]],[[120245,120245],\\\"mapped\\\",[118]],[[120246,120246],\\\"mapped\\\",[119]],[[120247,120247],\\\"mapped\\\",[120]],[[120248,120248],\\\"mapped\\\",[121]],[[120249,120249],\\\"mapped\\\",[122]],[[120250,120250],\\\"mapped\\\",[97]],[[120251,120251],\\\"mapped\\\",[98]],[[120252,120252],\\\"mapped\\\",[99]],[[120253,120253],\\\"mapped\\\",[100]],[[120254,120254],\\\"mapped\\\",[101]],[[120255,120255],\\\"mapped\\\",[102]],[[120256,120256],\\\"mapped\\\",[103]],[[120257,120257],\\\"mapped\\\",[104]],[[120258,120258],\\\"mapped\\\",[105]],[[120259,120259],\\\"mapped\\\",[106]],[[120260,120260],\\\"mapped\\\",[107]],[[120261,120261],\\\"mapped\\\",[108]],[[120262,120262],\\\"mapped\\\",[109]],[[120263,120263],\\\"mapped\\\",[110]],[[120264,120264],\\\"mapped\\\",[111]],[[120265,120265],\\\"mapped\\\",[112]],[[120266,120266],\\\"mapped\\\",[113]],[[120267,120267],\\\"mapped\\\",[114]],[[120268,120268],\\\"mapped\\\",[115]],[[120269,120269],\\\"mapped\\\",[116]],[[120270,120270],\\\"mapped\\\",[117]],[[120271,120271],\\\"mapped\\\",[118]],[[120272,120272],\\\"mapped\\\",[119]],[[120273,120273],\\\"mapped\\\",[120]],[[120274,120274],\\\"mapped\\\",[121]],[[120275,120275],\\\"mapped\\\",[122]],[[120276,120276],\\\"mapped\\\",[97]],[[120277,120277],\\\"mapped\\\",[98]],[[120278,120278],\\\"mapped\\\",[99]],[[120279,120279],\\\"mapped\\\",[100]],[[120280,120280],\\\"mapped\\\",[101]],[[120281,120281],\\\"mapped\\\",[102]],[[120282,120282],\\\"mapped\\\",[103]],[[120283,120283],\\\"mapped\\\",[104]],[[120284,120284],\\\"mapped\\\",[105]],[[120285,120285],\\\"mapped\\\",[106]],[[120286,120286],\\\"mapped\\\",[107]],[[120287,120287],\\\"mapped\\\",[108]],[[120288,120288],\\\"mapped\\\",[109]],[[120289,120289],\\\"mapped\\\",[110]],[[120290,120290],\\\"mapped\\\",[111]],[[120291,120291],\\\"mapped\\\",[112]],[[120292,120292],\\\"mapped\\\",[113]],[[120293,120293],\\\"mapped\\\",[114]],[[120294,120294],\\\"mapped\\\",[115]],[[120295,120295],\\\"mapped\\\",[116]],[[120296,120296],\\\"mapped\\\",[117]],[[120297,120297],\\\"mapped\\\",[118]],[[120298,120298],\\\"mapped\\\",[119]],[[120299,120299],\\\"mapped\\\",[120]],[[120300,120300],\\\"mapped\\\",[121]],[[120301,120301],\\\"mapped\\\",[122]],[[120302,120302],\\\"mapped\\\",[97]],[[120303,120303],\\\"mapped\\\",[98]],[[120304,120304],\\\"mapped\\\",[99]],[[120305,120305],\\\"mapped\\\",[100]],[[120306,120306],\\\"mapped\\\",[101]],[[120307,120307],\\\"mapped\\\",[102]],[[120308,120308],\\\"mapped\\\",[103]],[[120309,120309],\\\"mapped\\\",[104]],[[120310,120310],\\\"mapped\\\",[105]],[[120311,120311],\\\"mapped\\\",[106]],[[120312,120312],\\\"mapped\\\",[107]],[[120313,120313],\\\"mapped\\\",[108]],[[120314,120314],\\\"mapped\\\",[109]],[[120315,120315],\\\"mapped\\\",[110]],[[120316,120316],\\\"mapped\\\",[111]],[[120317,120317],\\\"mapped\\\",[112]],[[120318,120318],\\\"mapped\\\",[113]],[[120319,120319],\\\"mapped\\\",[114]],[[120320,120320],\\\"mapped\\\",[115]],[[120321,120321],\\\"mapped\\\",[116]],[[120322,120322],\\\"mapped\\\",[117]],[[120323,120323],\\\"mapped\\\",[118]],[[120324,120324],\\\"mapped\\\",[119]],[[120325,120325],\\\"mapped\\\",[120]],[[120326,120326],\\\"mapped\\\",[121]],[[120327,120327],\\\"mapped\\\",[122]],[[120328,120328],\\\"mapped\\\",[97]],[[120329,120329],\\\"mapped\\\",[98]],[[120330,120330],\\\"mapped\\\",[99]],[[120331,120331],\\\"mapped\\\",[100]],[[120332,120332],\\\"mapped\\\",[101]],[[120333,120333],\\\"mapped\\\",[102]],[[120334,120334],\\\"mapped\\\",[103]],[[120335,120335],\\\"mapped\\\",[104]],[[120336,120336],\\\"mapped\\\",[105]],[[120337,120337],\\\"mapped\\\",[106]],[[120338,120338],\\\"mapped\\\",[107]],[[120339,120339],\\\"mapped\\\",[108]],[[120340,120340],\\\"mapped\\\",[109]],[[120341,120341],\\\"mapped\\\",[110]],[[120342,120342],\\\"mapped\\\",[111]],[[120343,120343],\\\"mapped\\\",[112]],[[120344,120344],\\\"mapped\\\",[113]],[[120345,120345],\\\"mapped\\\",[114]],[[120346,120346],\\\"mapped\\\",[115]],[[120347,120347],\\\"mapped\\\",[116]],[[120348,120348],\\\"mapped\\\",[117]],[[120349,120349],\\\"mapped\\\",[118]],[[120350,120350],\\\"mapped\\\",[119]],[[120351,120351],\\\"mapped\\\",[120]],[[120352,120352],\\\"mapped\\\",[121]],[[120353,120353],\\\"mapped\\\",[122]],[[120354,120354],\\\"mapped\\\",[97]],[[120355,120355],\\\"mapped\\\",[98]],[[120356,120356],\\\"mapped\\\",[99]],[[120357,120357],\\\"mapped\\\",[100]],[[120358,120358],\\\"mapped\\\",[101]],[[120359,120359],\\\"mapped\\\",[102]],[[120360,120360],\\\"mapped\\\",[103]],[[120361,120361],\\\"mapped\\\",[104]],[[120362,120362],\\\"mapped\\\",[105]],[[120363,120363],\\\"mapped\\\",[106]],[[120364,120364],\\\"mapped\\\",[107]],[[120365,120365],\\\"mapped\\\",[108]],[[120366,120366],\\\"mapped\\\",[109]],[[120367,120367],\\\"mapped\\\",[110]],[[120368,120368],\\\"mapped\\\",[111]],[[120369,120369],\\\"mapped\\\",[112]],[[120370,120370],\\\"mapped\\\",[113]],[[120371,120371],\\\"mapped\\\",[114]],[[120372,120372],\\\"mapped\\\",[115]],[[120373,120373],\\\"mapped\\\",[116]],[[120374,120374],\\\"mapped\\\",[117]],[[120375,120375],\\\"mapped\\\",[118]],[[120376,120376],\\\"mapped\\\",[119]],[[120377,120377],\\\"mapped\\\",[120]],[[120378,120378],\\\"mapped\\\",[121]],[[120379,120379],\\\"mapped\\\",[122]],[[120380,120380],\\\"mapped\\\",[97]],[[120381,120381],\\\"mapped\\\",[98]],[[120382,120382],\\\"mapped\\\",[99]],[[120383,120383],\\\"mapped\\\",[100]],[[120384,120384],\\\"mapped\\\",[101]],[[120385,120385],\\\"mapped\\\",[102]],[[120386,120386],\\\"mapped\\\",[103]],[[120387,120387],\\\"mapped\\\",[104]],[[120388,120388],\\\"mapped\\\",[105]],[[120389,120389],\\\"mapped\\\",[106]],[[120390,120390],\\\"mapped\\\",[107]],[[120391,120391],\\\"mapped\\\",[108]],[[120392,120392],\\\"mapped\\\",[109]],[[120393,120393],\\\"mapped\\\",[110]],[[120394,120394],\\\"mapped\\\",[111]],[[120395,120395],\\\"mapped\\\",[112]],[[120396,120396],\\\"mapped\\\",[113]],[[120397,120397],\\\"mapped\\\",[114]],[[120398,120398],\\\"mapped\\\",[115]],[[120399,120399],\\\"mapped\\\",[116]],[[120400,120400],\\\"mapped\\\",[117]],[[120401,120401],\\\"mapped\\\",[118]],[[120402,120402],\\\"mapped\\\",[119]],[[120403,120403],\\\"mapped\\\",[120]],[[120404,120404],\\\"mapped\\\",[121]],[[120405,120405],\\\"mapped\\\",[122]],[[120406,120406],\\\"mapped\\\",[97]],[[120407,120407],\\\"mapped\\\",[98]],[[120408,120408],\\\"mapped\\\",[99]],[[120409,120409],\\\"mapped\\\",[100]],[[120410,120410],\\\"mapped\\\",[101]],[[120411,120411],\\\"mapped\\\",[102]],[[120412,120412],\\\"mapped\\\",[103]],[[120413,120413],\\\"mapped\\\",[104]],[[120414,120414],\\\"mapped\\\",[105]],[[120415,120415],\\\"mapped\\\",[106]],[[120416,120416],\\\"mapped\\\",[107]],[[120417,120417],\\\"mapped\\\",[108]],[[120418,120418],\\\"mapped\\\",[109]],[[120419,120419],\\\"mapped\\\",[110]],[[120420,120420],\\\"mapped\\\",[111]],[[120421,120421],\\\"mapped\\\",[112]],[[120422,120422],\\\"mapped\\\",[113]],[[120423,120423],\\\"mapped\\\",[114]],[[120424,120424],\\\"mapped\\\",[115]],[[120425,120425],\\\"mapped\\\",[116]],[[120426,120426],\\\"mapped\\\",[117]],[[120427,120427],\\\"mapped\\\",[118]],[[120428,120428],\\\"mapped\\\",[119]],[[120429,120429],\\\"mapped\\\",[120]],[[120430,120430],\\\"mapped\\\",[121]],[[120431,120431],\\\"mapped\\\",[122]],[[120432,120432],\\\"mapped\\\",[97]],[[120433,120433],\\\"mapped\\\",[98]],[[120434,120434],\\\"mapped\\\",[99]],[[120435,120435],\\\"mapped\\\",[100]],[[120436,120436],\\\"mapped\\\",[101]],[[120437,120437],\\\"mapped\\\",[102]],[[120438,120438],\\\"mapped\\\",[103]],[[120439,120439],\\\"mapped\\\",[104]],[[120440,120440],\\\"mapped\\\",[105]],[[120441,120441],\\\"mapped\\\",[106]],[[120442,120442],\\\"mapped\\\",[107]],[[120443,120443],\\\"mapped\\\",[108]],[[120444,120444],\\\"mapped\\\",[109]],[[120445,120445],\\\"mapped\\\",[110]],[[120446,120446],\\\"mapped\\\",[111]],[[120447,120447],\\\"mapped\\\",[112]],[[120448,120448],\\\"mapped\\\",[113]],[[120449,120449],\\\"mapped\\\",[114]],[[120450,120450],\\\"mapped\\\",[115]],[[120451,120451],\\\"mapped\\\",[116]],[[120452,120452],\\\"mapped\\\",[117]],[[120453,120453],\\\"mapped\\\",[118]],[[120454,120454],\\\"mapped\\\",[119]],[[120455,120455],\\\"mapped\\\",[120]],[[120456,120456],\\\"mapped\\\",[121]],[[120457,120457],\\\"mapped\\\",[122]],[[120458,120458],\\\"mapped\\\",[97]],[[120459,120459],\\\"mapped\\\",[98]],[[120460,120460],\\\"mapped\\\",[99]],[[120461,120461],\\\"mapped\\\",[100]],[[120462,120462],\\\"mapped\\\",[101]],[[120463,120463],\\\"mapped\\\",[102]],[[120464,120464],\\\"mapped\\\",[103]],[[120465,120465],\\\"mapped\\\",[104]],[[120466,120466],\\\"mapped\\\",[105]],[[120467,120467],\\\"mapped\\\",[106]],[[120468,120468],\\\"mapped\\\",[107]],[[120469,120469],\\\"mapped\\\",[108]],[[120470,120470],\\\"mapped\\\",[109]],[[120471,120471],\\\"mapped\\\",[110]],[[120472,120472],\\\"mapped\\\",[111]],[[120473,120473],\\\"mapped\\\",[112]],[[120474,120474],\\\"mapped\\\",[113]],[[120475,120475],\\\"mapped\\\",[114]],[[120476,120476],\\\"mapped\\\",[115]],[[120477,120477],\\\"mapped\\\",[116]],[[120478,120478],\\\"mapped\\\",[117]],[[120479,120479],\\\"mapped\\\",[118]],[[120480,120480],\\\"mapped\\\",[119]],[[120481,120481],\\\"mapped\\\",[120]],[[120482,120482],\\\"mapped\\\",[121]],[[120483,120483],\\\"mapped\\\",[122]],[[120484,120484],\\\"mapped\\\",[305]],[[120485,120485],\\\"mapped\\\",[567]],[[120486,120487],\\\"disallowed\\\"],[[120488,120488],\\\"mapped\\\",[945]],[[120489,120489],\\\"mapped\\\",[946]],[[120490,120490],\\\"mapped\\\",[947]],[[120491,120491],\\\"mapped\\\",[948]],[[120492,120492],\\\"mapped\\\",[949]],[[120493,120493],\\\"mapped\\\",[950]],[[120494,120494],\\\"mapped\\\",[951]],[[120495,120495],\\\"mapped\\\",[952]],[[120496,120496],\\\"mapped\\\",[953]],[[120497,120497],\\\"mapped\\\",[954]],[[120498,120498],\\\"mapped\\\",[955]],[[120499,120499],\\\"mapped\\\",[956]],[[120500,120500],\\\"mapped\\\",[957]],[[120501,120501],\\\"mapped\\\",[958]],[[120502,120502],\\\"mapped\\\",[959]],[[120503,120503],\\\"mapped\\\",[960]],[[120504,120504],\\\"mapped\\\",[961]],[[120505,120505],\\\"mapped\\\",[952]],[[120506,120506],\\\"mapped\\\",[963]],[[120507,120507],\\\"mapped\\\",[964]],[[120508,120508],\\\"mapped\\\",[965]],[[120509,120509],\\\"mapped\\\",[966]],[[120510,120510],\\\"mapped\\\",[967]],[[120511,120511],\\\"mapped\\\",[968]],[[120512,120512],\\\"mapped\\\",[969]],[[120513,120513],\\\"mapped\\\",[8711]],[[120514,120514],\\\"mapped\\\",[945]],[[120515,120515],\\\"mapped\\\",[946]],[[120516,120516],\\\"mapped\\\",[947]],[[120517,120517],\\\"mapped\\\",[948]],[[120518,120518],\\\"mapped\\\",[949]],[[120519,120519],\\\"mapped\\\",[950]],[[120520,120520],\\\"mapped\\\",[951]],[[120521,120521],\\\"mapped\\\",[952]],[[120522,120522],\\\"mapped\\\",[953]],[[120523,120523],\\\"mapped\\\",[954]],[[120524,120524],\\\"mapped\\\",[955]],[[120525,120525],\\\"mapped\\\",[956]],[[120526,120526],\\\"mapped\\\",[957]],[[120527,120527],\\\"mapped\\\",[958]],[[120528,120528],\\\"mapped\\\",[959]],[[120529,120529],\\\"mapped\\\",[960]],[[120530,120530],\\\"mapped\\\",[961]],[[120531,120532],\\\"mapped\\\",[963]],[[120533,120533],\\\"mapped\\\",[964]],[[120534,120534],\\\"mapped\\\",[965]],[[120535,120535],\\\"mapped\\\",[966]],[[120536,120536],\\\"mapped\\\",[967]],[[120537,120537],\\\"mapped\\\",[968]],[[120538,120538],\\\"mapped\\\",[969]],[[120539,120539],\\\"mapped\\\",[8706]],[[120540,120540],\\\"mapped\\\",[949]],[[120541,120541],\\\"mapped\\\",[952]],[[120542,120542],\\\"mapped\\\",[954]],[[120543,120543],\\\"mapped\\\",[966]],[[120544,120544],\\\"mapped\\\",[961]],[[120545,120545],\\\"mapped\\\",[960]],[[120546,120546],\\\"mapped\\\",[945]],[[120547,120547],\\\"mapped\\\",[946]],[[120548,120548],\\\"mapped\\\",[947]],[[120549,120549],\\\"mapped\\\",[948]],[[120550,120550],\\\"mapped\\\",[949]],[[120551,120551],\\\"mapped\\\",[950]],[[120552,120552],\\\"mapped\\\",[951]],[[120553,120553],\\\"mapped\\\",[952]],[[120554,120554],\\\"mapped\\\",[953]],[[120555,120555],\\\"mapped\\\",[954]],[[120556,120556],\\\"mapped\\\",[955]],[[120557,120557],\\\"mapped\\\",[956]],[[120558,120558],\\\"mapped\\\",[957]],[[120559,120559],\\\"mapped\\\",[958]],[[120560,120560],\\\"mapped\\\",[959]],[[120561,120561],\\\"mapped\\\",[960]],[[120562,120562],\\\"mapped\\\",[961]],[[120563,120563],\\\"mapped\\\",[952]],[[120564,120564],\\\"mapped\\\",[963]],[[120565,120565],\\\"mapped\\\",[964]],[[120566,120566],\\\"mapped\\\",[965]],[[120567,120567],\\\"mapped\\\",[966]],[[120568,120568],\\\"mapped\\\",[967]],[[120569,120569],\\\"mapped\\\",[968]],[[120570,120570],\\\"mapped\\\",[969]],[[120571,120571],\\\"mapped\\\",[8711]],[[120572,120572],\\\"mapped\\\",[945]],[[120573,120573],\\\"mapped\\\",[946]],[[120574,120574],\\\"mapped\\\",[947]],[[120575,120575],\\\"mapped\\\",[948]],[[120576,120576],\\\"mapped\\\",[949]],[[120577,120577],\\\"mapped\\\",[950]],[[120578,120578],\\\"mapped\\\",[951]],[[120579,120579],\\\"mapped\\\",[952]],[[120580,120580],\\\"mapped\\\",[953]],[[120581,120581],\\\"mapped\\\",[954]],[[120582,120582],\\\"mapped\\\",[955]],[[120583,120583],\\\"mapped\\\",[956]],[[120584,120584],\\\"mapped\\\",[957]],[[120585,120585],\\\"mapped\\\",[958]],[[120586,120586],\\\"mapped\\\",[959]],[[120587,120587],\\\"mapped\\\",[960]],[[120588,120588],\\\"mapped\\\",[961]],[[120589,120590],\\\"mapped\\\",[963]],[[120591,120591],\\\"mapped\\\",[964]],[[120592,120592],\\\"mapped\\\",[965]],[[120593,120593],\\\"mapped\\\",[966]],[[120594,120594],\\\"mapped\\\",[967]],[[120595,120595],\\\"mapped\\\",[968]],[[120596,120596],\\\"mapped\\\",[969]],[[120597,120597],\\\"mapped\\\",[8706]],[[120598,120598],\\\"mapped\\\",[949]],[[120599,120599],\\\"mapped\\\",[952]],[[120600,120600],\\\"mapped\\\",[954]],[[120601,120601],\\\"mapped\\\",[966]],[[120602,120602],\\\"mapped\\\",[961]],[[120603,120603],\\\"mapped\\\",[960]],[[120604,120604],\\\"mapped\\\",[945]],[[120605,120605],\\\"mapped\\\",[946]],[[120606,120606],\\\"mapped\\\",[947]],[[120607,120607],\\\"mapped\\\",[948]],[[120608,120608],\\\"mapped\\\",[949]],[[120609,120609],\\\"mapped\\\",[950]],[[120610,120610],\\\"mapped\\\",[951]],[[120611,120611],\\\"mapped\\\",[952]],[[120612,120612],\\\"mapped\\\",[953]],[[120613,120613],\\\"mapped\\\",[954]],[[120614,120614],\\\"mapped\\\",[955]],[[120615,120615],\\\"mapped\\\",[956]],[[120616,120616],\\\"mapped\\\",[957]],[[120617,120617],\\\"mapped\\\",[958]],[[120618,120618],\\\"mapped\\\",[959]],[[120619,120619],\\\"mapped\\\",[960]],[[120620,120620],\\\"mapped\\\",[961]],[[120621,120621],\\\"mapped\\\",[952]],[[120622,120622],\\\"mapped\\\",[963]],[[120623,120623],\\\"mapped\\\",[964]],[[120624,120624],\\\"mapped\\\",[965]],[[120625,120625],\\\"mapped\\\",[966]],[[120626,120626],\\\"mapped\\\",[967]],[[120627,120627],\\\"mapped\\\",[968]],[[120628,120628],\\\"mapped\\\",[969]],[[120629,120629],\\\"mapped\\\",[8711]],[[120630,120630],\\\"mapped\\\",[945]],[[120631,120631],\\\"mapped\\\",[946]],[[120632,120632],\\\"mapped\\\",[947]],[[120633,120633],\\\"mapped\\\",[948]],[[120634,120634],\\\"mapped\\\",[949]],[[120635,120635],\\\"mapped\\\",[950]],[[120636,120636],\\\"mapped\\\",[951]],[[120637,120637],\\\"mapped\\\",[952]],[[120638,120638],\\\"mapped\\\",[953]],[[120639,120639],\\\"mapped\\\",[954]],[[120640,120640],\\\"mapped\\\",[955]],[[120641,120641],\\\"mapped\\\",[956]],[[120642,120642],\\\"mapped\\\",[957]],[[120643,120643],\\\"mapped\\\",[958]],[[120644,120644],\\\"mapped\\\",[959]],[[120645,120645],\\\"mapped\\\",[960]],[[120646,120646],\\\"mapped\\\",[961]],[[120647,120648],\\\"mapped\\\",[963]],[[120649,120649],\\\"mapped\\\",[964]],[[120650,120650],\\\"mapped\\\",[965]],[[120651,120651],\\\"mapped\\\",[966]],[[120652,120652],\\\"mapped\\\",[967]],[[120653,120653],\\\"mapped\\\",[968]],[[120654,120654],\\\"mapped\\\",[969]],[[120655,120655],\\\"mapped\\\",[8706]],[[120656,120656],\\\"mapped\\\",[949]],[[120657,120657],\\\"mapped\\\",[952]],[[120658,120658],\\\"mapped\\\",[954]],[[120659,120659],\\\"mapped\\\",[966]],[[120660,120660],\\\"mapped\\\",[961]],[[120661,120661],\\\"mapped\\\",[960]],[[120662,120662],\\\"mapped\\\",[945]],[[120663,120663],\\\"mapped\\\",[946]],[[120664,120664],\\\"mapped\\\",[947]],[[120665,120665],\\\"mapped\\\",[948]],[[120666,120666],\\\"mapped\\\",[949]],[[120667,120667],\\\"mapped\\\",[950]],[[120668,120668],\\\"mapped\\\",[951]],[[120669,120669],\\\"mapped\\\",[952]],[[120670,120670],\\\"mapped\\\",[953]],[[120671,120671],\\\"mapped\\\",[954]],[[120672,120672],\\\"mapped\\\",[955]],[[120673,120673],\\\"mapped\\\",[956]],[[120674,120674],\\\"mapped\\\",[957]],[[120675,120675],\\\"mapped\\\",[958]],[[120676,120676],\\\"mapped\\\",[959]],[[120677,120677],\\\"mapped\\\",[960]],[[120678,120678],\\\"mapped\\\",[961]],[[120679,120679],\\\"mapped\\\",[952]],[[120680,120680],\\\"mapped\\\",[963]],[[120681,120681],\\\"mapped\\\",[964]],[[120682,120682],\\\"mapped\\\",[965]],[[120683,120683],\\\"mapped\\\",[966]],[[120684,120684],\\\"mapped\\\",[967]],[[120685,120685],\\\"mapped\\\",[968]],[[120686,120686],\\\"mapped\\\",[969]],[[120687,120687],\\\"mapped\\\",[8711]],[[120688,120688],\\\"mapped\\\",[945]],[[120689,120689],\\\"mapped\\\",[946]],[[120690,120690],\\\"mapped\\\",[947]],[[120691,120691],\\\"mapped\\\",[948]],[[120692,120692],\\\"mapped\\\",[949]],[[120693,120693],\\\"mapped\\\",[950]],[[120694,120694],\\\"mapped\\\",[951]],[[120695,120695],\\\"mapped\\\",[952]],[[120696,120696],\\\"mapped\\\",[953]],[[120697,120697],\\\"mapped\\\",[954]],[[120698,120698],\\\"mapped\\\",[955]],[[120699,120699],\\\"mapped\\\",[956]],[[120700,120700],\\\"mapped\\\",[957]],[[120701,120701],\\\"mapped\\\",[958]],[[120702,120702],\\\"mapped\\\",[959]],[[120703,120703],\\\"mapped\\\",[960]],[[120704,120704],\\\"mapped\\\",[961]],[[120705,120706],\\\"mapped\\\",[963]],[[120707,120707],\\\"mapped\\\",[964]],[[120708,120708],\\\"mapped\\\",[965]],[[120709,120709],\\\"mapped\\\",[966]],[[120710,120710],\\\"mapped\\\",[967]],[[120711,120711],\\\"mapped\\\",[968]],[[120712,120712],\\\"mapped\\\",[969]],[[120713,120713],\\\"mapped\\\",[8706]],[[120714,120714],\\\"mapped\\\",[949]],[[120715,120715],\\\"mapped\\\",[952]],[[120716,120716],\\\"mapped\\\",[954]],[[120717,120717],\\\"mapped\\\",[966]],[[120718,120718],\\\"mapped\\\",[961]],[[120719,120719],\\\"mapped\\\",[960]],[[120720,120720],\\\"mapped\\\",[945]],[[120721,120721],\\\"mapped\\\",[946]],[[120722,120722],\\\"mapped\\\",[947]],[[120723,120723],\\\"mapped\\\",[948]],[[120724,120724],\\\"mapped\\\",[949]],[[120725,120725],\\\"mapped\\\",[950]],[[120726,120726],\\\"mapped\\\",[951]],[[120727,120727],\\\"mapped\\\",[952]],[[120728,120728],\\\"mapped\\\",[953]],[[120729,120729],\\\"mapped\\\",[954]],[[120730,120730],\\\"mapped\\\",[955]],[[120731,120731],\\\"mapped\\\",[956]],[[120732,120732],\\\"mapped\\\",[957]],[[120733,120733],\\\"mapped\\\",[958]],[[120734,120734],\\\"mapped\\\",[959]],[[120735,120735],\\\"mapped\\\",[960]],[[120736,120736],\\\"mapped\\\",[961]],[[120737,120737],\\\"mapped\\\",[952]],[[120738,120738],\\\"mapped\\\",[963]],[[120739,120739],\\\"mapped\\\",[964]],[[120740,120740],\\\"mapped\\\",[965]],[[120741,120741],\\\"mapped\\\",[966]],[[120742,120742],\\\"mapped\\\",[967]],[[120743,120743],\\\"mapped\\\",[968]],[[120744,120744],\\\"mapped\\\",[969]],[[120745,120745],\\\"mapped\\\",[8711]],[[120746,120746],\\\"mapped\\\",[945]],[[120747,120747],\\\"mapped\\\",[946]],[[120748,120748],\\\"mapped\\\",[947]],[[120749,120749],\\\"mapped\\\",[948]],[[120750,120750],\\\"mapped\\\",[949]],[[120751,120751],\\\"mapped\\\",[950]],[[120752,120752],\\\"mapped\\\",[951]],[[120753,120753],\\\"mapped\\\",[952]],[[120754,120754],\\\"mapped\\\",[953]],[[120755,120755],\\\"mapped\\\",[954]],[[120756,120756],\\\"mapped\\\",[955]],[[120757,120757],\\\"mapped\\\",[956]],[[120758,120758],\\\"mapped\\\",[957]],[[120759,120759],\\\"mapped\\\",[958]],[[120760,120760],\\\"mapped\\\",[959]],[[120761,120761],\\\"mapped\\\",[960]],[[120762,120762],\\\"mapped\\\",[961]],[[120763,120764],\\\"mapped\\\",[963]],[[120765,120765],\\\"mapped\\\",[964]],[[120766,120766],\\\"mapped\\\",[965]],[[120767,120767],\\\"mapped\\\",[966]],[[120768,120768],\\\"mapped\\\",[967]],[[120769,120769],\\\"mapped\\\",[968]],[[120770,120770],\\\"mapped\\\",[969]],[[120771,120771],\\\"mapped\\\",[8706]],[[120772,120772],\\\"mapped\\\",[949]],[[120773,120773],\\\"mapped\\\",[952]],[[120774,120774],\\\"mapped\\\",[954]],[[120775,120775],\\\"mapped\\\",[966]],[[120776,120776],\\\"mapped\\\",[961]],[[120777,120777],\\\"mapped\\\",[960]],[[120778,120779],\\\"mapped\\\",[989]],[[120780,120781],\\\"disallowed\\\"],[[120782,120782],\\\"mapped\\\",[48]],[[120783,120783],\\\"mapped\\\",[49]],[[120784,120784],\\\"mapped\\\",[50]],[[120785,120785],\\\"mapped\\\",[51]],[[120786,120786],\\\"mapped\\\",[52]],[[120787,120787],\\\"mapped\\\",[53]],[[120788,120788],\\\"mapped\\\",[54]],[[120789,120789],\\\"mapped\\\",[55]],[[120790,120790],\\\"mapped\\\",[56]],[[120791,120791],\\\"mapped\\\",[57]],[[120792,120792],\\\"mapped\\\",[48]],[[120793,120793],\\\"mapped\\\",[49]],[[120794,120794],\\\"mapped\\\",[50]],[[120795,120795],\\\"mapped\\\",[51]],[[120796,120796],\\\"mapped\\\",[52]],[[120797,120797],\\\"mapped\\\",[53]],[[120798,120798],\\\"mapped\\\",[54]],[[120799,120799],\\\"mapped\\\",[55]],[[120800,120800],\\\"mapped\\\",[56]],[[120801,120801],\\\"mapped\\\",[57]],[[120802,120802],\\\"mapped\\\",[48]],[[120803,120803],\\\"mapped\\\",[49]],[[120804,120804],\\\"mapped\\\",[50]],[[120805,120805],\\\"mapped\\\",[51]],[[120806,120806],\\\"mapped\\\",[52]],[[120807,120807],\\\"mapped\\\",[53]],[[120808,120808],\\\"mapped\\\",[54]],[[120809,120809],\\\"mapped\\\",[55]],[[120810,120810],\\\"mapped\\\",[56]],[[120811,120811],\\\"mapped\\\",[57]],[[120812,120812],\\\"mapped\\\",[48]],[[120813,120813],\\\"mapped\\\",[49]],[[120814,120814],\\\"mapped\\\",[50]],[[120815,120815],\\\"mapped\\\",[51]],[[120816,120816],\\\"mapped\\\",[52]],[[120817,120817],\\\"mapped\\\",[53]],[[120818,120818],\\\"mapped\\\",[54]],[[120819,120819],\\\"mapped\\\",[55]],[[120820,120820],\\\"mapped\\\",[56]],[[120821,120821],\\\"mapped\\\",[57]],[[120822,120822],\\\"mapped\\\",[48]],[[120823,120823],\\\"mapped\\\",[49]],[[120824,120824],\\\"mapped\\\",[50]],[[120825,120825],\\\"mapped\\\",[51]],[[120826,120826],\\\"mapped\\\",[52]],[[120827,120827],\\\"mapped\\\",[53]],[[120828,120828],\\\"mapped\\\",[54]],[[120829,120829],\\\"mapped\\\",[55]],[[120830,120830],\\\"mapped\\\",[56]],[[120831,120831],\\\"mapped\\\",[57]],[[120832,121343],\\\"valid\\\",[],\\\"NV8\\\"],[[121344,121398],\\\"valid\\\"],[[121399,121402],\\\"valid\\\",[],\\\"NV8\\\"],[[121403,121452],\\\"valid\\\"],[[121453,121460],\\\"valid\\\",[],\\\"NV8\\\"],[[121461,121461],\\\"valid\\\"],[[121462,121475],\\\"valid\\\",[],\\\"NV8\\\"],[[121476,121476],\\\"valid\\\"],[[121477,121483],\\\"valid\\\",[],\\\"NV8\\\"],[[121484,121498],\\\"disallowed\\\"],[[121499,121503],\\\"valid\\\"],[[121504,121504],\\\"disallowed\\\"],[[121505,121519],\\\"valid\\\"],[[121520,124927],\\\"disallowed\\\"],[[124928,125124],\\\"valid\\\"],[[125125,125126],\\\"disallowed\\\"],[[125127,125135],\\\"valid\\\",[],\\\"NV8\\\"],[[125136,125142],\\\"valid\\\"],[[125143,126463],\\\"disallowed\\\"],[[126464,126464],\\\"mapped\\\",[1575]],[[126465,126465],\\\"mapped\\\",[1576]],[[126466,126466],\\\"mapped\\\",[1580]],[[126467,126467],\\\"mapped\\\",[1583]],[[126468,126468],\\\"disallowed\\\"],[[126469,126469],\\\"mapped\\\",[1608]],[[126470,126470],\\\"mapped\\\",[1586]],[[126471,126471],\\\"mapped\\\",[1581]],[[126472,126472],\\\"mapped\\\",[1591]],[[126473,126473],\\\"mapped\\\",[1610]],[[126474,126474],\\\"mapped\\\",[1603]],[[126475,126475],\\\"mapped\\\",[1604]],[[126476,126476],\\\"mapped\\\",[1605]],[[126477,126477],\\\"mapped\\\",[1606]],[[126478,126478],\\\"mapped\\\",[1587]],[[126479,126479],\\\"mapped\\\",[1593]],[[126480,126480],\\\"mapped\\\",[1601]],[[126481,126481],\\\"mapped\\\",[1589]],[[126482,126482],\\\"mapped\\\",[1602]],[[126483,126483],\\\"mapped\\\",[1585]],[[126484,126484],\\\"mapped\\\",[1588]],[[126485,126485],\\\"mapped\\\",[1578]],[[126486,126486],\\\"mapped\\\",[1579]],[[126487,126487],\\\"mapped\\\",[1582]],[[126488,126488],\\\"mapped\\\",[1584]],[[126489,126489],\\\"mapped\\\",[1590]],[[126490,126490],\\\"mapped\\\",[1592]],[[126491,126491],\\\"mapped\\\",[1594]],[[126492,126492],\\\"mapped\\\",[1646]],[[126493,126493],\\\"mapped\\\",[1722]],[[126494,126494],\\\"mapped\\\",[1697]],[[126495,126495],\\\"mapped\\\",[1647]],[[126496,126496],\\\"disallowed\\\"],[[126497,126497],\\\"mapped\\\",[1576]],[[126498,126498],\\\"mapped\\\",[1580]],[[126499,126499],\\\"disallowed\\\"],[[126500,126500],\\\"mapped\\\",[1607]],[[126501,126502],\\\"disallowed\\\"],[[126503,126503],\\\"mapped\\\",[1581]],[[126504,126504],\\\"disallowed\\\"],[[126505,126505],\\\"mapped\\\",[1610]],[[126506,126506],\\\"mapped\\\",[1603]],[[126507,126507],\\\"mapped\\\",[1604]],[[126508,126508],\\\"mapped\\\",[1605]],[[126509,126509],\\\"mapped\\\",[1606]],[[126510,126510],\\\"mapped\\\",[1587]],[[126511,126511],\\\"mapped\\\",[1593]],[[126512,126512],\\\"mapped\\\",[1601]],[[126513,126513],\\\"mapped\\\",[1589]],[[126514,126514],\\\"mapped\\\",[1602]],[[126515,126515],\\\"disallowed\\\"],[[126516,126516],\\\"mapped\\\",[1588]],[[126517,126517],\\\"mapped\\\",[1578]],[[126518,126518],\\\"mapped\\\",[1579]],[[126519,126519],\\\"mapped\\\",[1582]],[[126520,126520],\\\"disallowed\\\"],[[126521,126521],\\\"mapped\\\",[1590]],[[126522,126522],\\\"disallowed\\\"],[[126523,126523],\\\"mapped\\\",[1594]],[[126524,126529],\\\"disallowed\\\"],[[126530,126530],\\\"mapped\\\",[1580]],[[126531,126534],\\\"disallowed\\\"],[[126535,126535],\\\"mapped\\\",[1581]],[[126536,126536],\\\"disallowed\\\"],[[126537,126537],\\\"mapped\\\",[1610]],[[126538,126538],\\\"disallowed\\\"],[[126539,126539],\\\"mapped\\\",[1604]],[[126540,126540],\\\"disallowed\\\"],[[126541,126541],\\\"mapped\\\",[1606]],[[126542,126542],\\\"mapped\\\",[1587]],[[126543,126543],\\\"mapped\\\",[1593]],[[126544,126544],\\\"disallowed\\\"],[[126545,126545],\\\"mapped\\\",[1589]],[[126546,126546],\\\"mapped\\\",[1602]],[[126547,126547],\\\"disallowed\\\"],[[126548,126548],\\\"mapped\\\",[1588]],[[126549,126550],\\\"disallowed\\\"],[[126551,126551],\\\"mapped\\\",[1582]],[[126552,126552],\\\"disallowed\\\"],[[126553,126553],\\\"mapped\\\",[1590]],[[126554,126554],\\\"disallowed\\\"],[[126555,126555],\\\"mapped\\\",[1594]],[[126556,126556],\\\"disallowed\\\"],[[126557,126557],\\\"mapped\\\",[1722]],[[126558,126558],\\\"disallowed\\\"],[[126559,126559],\\\"mapped\\\",[1647]],[[126560,126560],\\\"disallowed\\\"],[[126561,126561],\\\"mapped\\\",[1576]],[[126562,126562],\\\"mapped\\\",[1580]],[[126563,126563],\\\"disallowed\\\"],[[126564,126564],\\\"mapped\\\",[1607]],[[126565,126566],\\\"disallowed\\\"],[[126567,126567],\\\"mapped\\\",[1581]],[[126568,126568],\\\"mapped\\\",[1591]],[[126569,126569],\\\"mapped\\\",[1610]],[[126570,126570],\\\"mapped\\\",[1603]],[[126571,126571],\\\"disallowed\\\"],[[126572,126572],\\\"mapped\\\",[1605]],[[126573,126573],\\\"mapped\\\",[1606]],[[126574,126574],\\\"mapped\\\",[1587]],[[126575,126575],\\\"mapped\\\",[1593]],[[126576,126576],\\\"mapped\\\",[1601]],[[126577,126577],\\\"mapped\\\",[1589]],[[126578,126578],\\\"mapped\\\",[1602]],[[126579,126579],\\\"disallowed\\\"],[[126580,126580],\\\"mapped\\\",[1588]],[[126581,126581],\\\"mapped\\\",[1578]],[[126582,126582],\\\"mapped\\\",[1579]],[[126583,126583],\\\"mapped\\\",[1582]],[[126584,126584],\\\"disallowed\\\"],[[126585,126585],\\\"mapped\\\",[1590]],[[126586,126586],\\\"mapped\\\",[1592]],[[126587,126587],\\\"mapped\\\",[1594]],[[126588,126588],\\\"mapped\\\",[1646]],[[126589,126589],\\\"disallowed\\\"],[[126590,126590],\\\"mapped\\\",[1697]],[[126591,126591],\\\"disallowed\\\"],[[126592,126592],\\\"mapped\\\",[1575]],[[126593,126593],\\\"mapped\\\",[1576]],[[126594,126594],\\\"mapped\\\",[1580]],[[126595,126595],\\\"mapped\\\",[1583]],[[126596,126596],\\\"mapped\\\",[1607]],[[126597,126597],\\\"mapped\\\",[1608]],[[126598,126598],\\\"mapped\\\",[1586]],[[126599,126599],\\\"mapped\\\",[1581]],[[126600,126600],\\\"mapped\\\",[1591]],[[126601,126601],\\\"mapped\\\",[1610]],[[126602,126602],\\\"disallowed\\\"],[[126603,126603],\\\"mapped\\\",[1604]],[[126604,126604],\\\"mapped\\\",[1605]],[[126605,126605],\\\"mapped\\\",[1606]],[[126606,126606],\\\"mapped\\\",[1587]],[[126607,126607],\\\"mapped\\\",[1593]],[[126608,126608],\\\"mapped\\\",[1601]],[[126609,126609],\\\"mapped\\\",[1589]],[[126610,126610],\\\"mapped\\\",[1602]],[[126611,126611],\\\"mapped\\\",[1585]],[[126612,126612],\\\"mapped\\\",[1588]],[[126613,126613],\\\"mapped\\\",[1578]],[[126614,126614],\\\"mapped\\\",[1579]],[[126615,126615],\\\"mapped\\\",[1582]],[[126616,126616],\\\"mapped\\\",[1584]],[[126617,126617],\\\"mapped\\\",[1590]],[[126618,126618],\\\"mapped\\\",[1592]],[[126619,126619],\\\"mapped\\\",[1594]],[[126620,126624],\\\"disallowed\\\"],[[126625,126625],\\\"mapped\\\",[1576]],[[126626,126626],\\\"mapped\\\",[1580]],[[126627,126627],\\\"mapped\\\",[1583]],[[126628,126628],\\\"disallowed\\\"],[[126629,126629],\\\"mapped\\\",[1608]],[[126630,126630],\\\"mapped\\\",[1586]],[[126631,126631],\\\"mapped\\\",[1581]],[[126632,126632],\\\"mapped\\\",[1591]],[[126633,126633],\\\"mapped\\\",[1610]],[[126634,126634],\\\"disallowed\\\"],[[126635,126635],\\\"mapped\\\",[1604]],[[126636,126636],\\\"mapped\\\",[1605]],[[126637,126637],\\\"mapped\\\",[1606]],[[126638,126638],\\\"mapped\\\",[1587]],[[126639,126639],\\\"mapped\\\",[1593]],[[126640,126640],\\\"mapped\\\",[1601]],[[126641,126641],\\\"mapped\\\",[1589]],[[126642,126642],\\\"mapped\\\",[1602]],[[126643,126643],\\\"mapped\\\",[1585]],[[126644,126644],\\\"mapped\\\",[1588]],[[126645,126645],\\\"mapped\\\",[1578]],[[126646,126646],\\\"mapped\\\",[1579]],[[126647,126647],\\\"mapped\\\",[1582]],[[126648,126648],\\\"mapped\\\",[1584]],[[126649,126649],\\\"mapped\\\",[1590]],[[126650,126650],\\\"mapped\\\",[1592]],[[126651,126651],\\\"mapped\\\",[1594]],[[126652,126703],\\\"disallowed\\\"],[[126704,126705],\\\"valid\\\",[],\\\"NV8\\\"],[[126706,126975],\\\"disallowed\\\"],[[126976,127019],\\\"valid\\\",[],\\\"NV8\\\"],[[127020,127023],\\\"disallowed\\\"],[[127024,127123],\\\"valid\\\",[],\\\"NV8\\\"],[[127124,127135],\\\"disallowed\\\"],[[127136,127150],\\\"valid\\\",[],\\\"NV8\\\"],[[127151,127152],\\\"disallowed\\\"],[[127153,127166],\\\"valid\\\",[],\\\"NV8\\\"],[[127167,127167],\\\"valid\\\",[],\\\"NV8\\\"],[[127168,127168],\\\"disallowed\\\"],[[127169,127183],\\\"valid\\\",[],\\\"NV8\\\"],[[127184,127184],\\\"disallowed\\\"],[[127185,127199],\\\"valid\\\",[],\\\"NV8\\\"],[[127200,127221],\\\"valid\\\",[],\\\"NV8\\\"],[[127222,127231],\\\"disallowed\\\"],[[127232,127232],\\\"disallowed\\\"],[[127233,127233],\\\"disallowed_STD3_mapped\\\",[48,44]],[[127234,127234],\\\"disallowed_STD3_mapped\\\",[49,44]],[[127235,127235],\\\"disallowed_STD3_mapped\\\",[50,44]],[[127236,127236],\\\"disallowed_STD3_mapped\\\",[51,44]],[[127237,127237],\\\"disallowed_STD3_mapped\\\",[52,44]],[[127238,127238],\\\"disallowed_STD3_mapped\\\",[53,44]],[[127239,127239],\\\"disallowed_STD3_mapped\\\",[54,44]],[[127240,127240],\\\"disallowed_STD3_mapped\\\",[55,44]],[[127241,127241],\\\"disallowed_STD3_mapped\\\",[56,44]],[[127242,127242],\\\"disallowed_STD3_mapped\\\",[57,44]],[[127243,127244],\\\"valid\\\",[],\\\"NV8\\\"],[[127245,127247],\\\"disallowed\\\"],[[127248,127248],\\\"disallowed_STD3_mapped\\\",[40,97,41]],[[127249,127249],\\\"disallowed_STD3_mapped\\\",[40,98,41]],[[127250,127250],\\\"disallowed_STD3_mapped\\\",[40,99,41]],[[127251,127251],\\\"disallowed_STD3_mapped\\\",[40,100,41]],[[127252,127252],\\\"disallowed_STD3_mapped\\\",[40,101,41]],[[127253,127253],\\\"disallowed_STD3_mapped\\\",[40,102,41]],[[127254,127254],\\\"disallowed_STD3_mapped\\\",[40,103,41]],[[127255,127255],\\\"disallowed_STD3_mapped\\\",[40,104,41]],[[127256,127256],\\\"disallowed_STD3_mapped\\\",[40,105,41]],[[127257,127257],\\\"disallowed_STD3_mapped\\\",[40,106,41]],[[127258,127258],\\\"disallowed_STD3_mapped\\\",[40,107,41]],[[127259,127259],\\\"disallowed_STD3_mapped\\\",[40,108,41]],[[127260,127260],\\\"disallowed_STD3_mapped\\\",[40,109,41]],[[127261,127261],\\\"disallowed_STD3_mapped\\\",[40,110,41]],[[127262,127262],\\\"disallowed_STD3_mapped\\\",[40,111,41]],[[127263,127263],\\\"disallowed_STD3_mapped\\\",[40,112,41]],[[127264,127264],\\\"disallowed_STD3_mapped\\\",[40,113,41]],[[127265,127265],\\\"disallowed_STD3_mapped\\\",[40,114,41]],[[127266,127266],\\\"disallowed_STD3_mapped\\\",[40,115,41]],[[127267,127267],\\\"disallowed_STD3_mapped\\\",[40,116,41]],[[127268,127268],\\\"disallowed_STD3_mapped\\\",[40,117,41]],[[127269,127269],\\\"disallowed_STD3_mapped\\\",[40,118,41]],[[127270,127270],\\\"disallowed_STD3_mapped\\\",[40,119,41]],[[127271,127271],\\\"disallowed_STD3_mapped\\\",[40,120,41]],[[127272,127272],\\\"disallowed_STD3_mapped\\\",[40,121,41]],[[127273,127273],\\\"disallowed_STD3_mapped\\\",[40,122,41]],[[127274,127274],\\\"mapped\\\",[12308,115,12309]],[[127275,127275],\\\"mapped\\\",[99]],[[127276,127276],\\\"mapped\\\",[114]],[[127277,127277],\\\"mapped\\\",[99,100]],[[127278,127278],\\\"mapped\\\",[119,122]],[[127279,127279],\\\"disallowed\\\"],[[127280,127280],\\\"mapped\\\",[97]],[[127281,127281],\\\"mapped\\\",[98]],[[127282,127282],\\\"mapped\\\",[99]],[[127283,127283],\\\"mapped\\\",[100]],[[127284,127284],\\\"mapped\\\",[101]],[[127285,127285],\\\"mapped\\\",[102]],[[127286,127286],\\\"mapped\\\",[103]],[[127287,127287],\\\"mapped\\\",[104]],[[127288,127288],\\\"mapped\\\",[105]],[[127289,127289],\\\"mapped\\\",[106]],[[127290,127290],\\\"mapped\\\",[107]],[[127291,127291],\\\"mapped\\\",[108]],[[127292,127292],\\\"mapped\\\",[109]],[[127293,127293],\\\"mapped\\\",[110]],[[127294,127294],\\\"mapped\\\",[111]],[[127295,127295],\\\"mapped\\\",[112]],[[127296,127296],\\\"mapped\\\",[113]],[[127297,127297],\\\"mapped\\\",[114]],[[127298,127298],\\\"mapped\\\",[115]],[[127299,127299],\\\"mapped\\\",[116]],[[127300,127300],\\\"mapped\\\",[117]],[[127301,127301],\\\"mapped\\\",[118]],[[127302,127302],\\\"mapped\\\",[119]],[[127303,127303],\\\"mapped\\\",[120]],[[127304,127304],\\\"mapped\\\",[121]],[[127305,127305],\\\"mapped\\\",[122]],[[127306,127306],\\\"mapped\\\",[104,118]],[[127307,127307],\\\"mapped\\\",[109,118]],[[127308,127308],\\\"mapped\\\",[115,100]],[[127309,127309],\\\"mapped\\\",[115,115]],[[127310,127310],\\\"mapped\\\",[112,112,118]],[[127311,127311],\\\"mapped\\\",[119,99]],[[127312,127318],\\\"valid\\\",[],\\\"NV8\\\"],[[127319,127319],\\\"valid\\\",[],\\\"NV8\\\"],[[127320,127326],\\\"valid\\\",[],\\\"NV8\\\"],[[127327,127327],\\\"valid\\\",[],\\\"NV8\\\"],[[127328,127337],\\\"valid\\\",[],\\\"NV8\\\"],[[127338,127338],\\\"mapped\\\",[109,99]],[[127339,127339],\\\"mapped\\\",[109,100]],[[127340,127343],\\\"disallowed\\\"],[[127344,127352],\\\"valid\\\",[],\\\"NV8\\\"],[[127353,127353],\\\"valid\\\",[],\\\"NV8\\\"],[[127354,127354],\\\"valid\\\",[],\\\"NV8\\\"],[[127355,127356],\\\"valid\\\",[],\\\"NV8\\\"],[[127357,127358],\\\"valid\\\",[],\\\"NV8\\\"],[[127359,127359],\\\"valid\\\",[],\\\"NV8\\\"],[[127360,127369],\\\"valid\\\",[],\\\"NV8\\\"],[[127370,127373],\\\"valid\\\",[],\\\"NV8\\\"],[[127374,127375],\\\"valid\\\",[],\\\"NV8\\\"],[[127376,127376],\\\"mapped\\\",[100,106]],[[127377,127386],\\\"valid\\\",[],\\\"NV8\\\"],[[127387,127461],\\\"disallowed\\\"],[[127462,127487],\\\"valid\\\",[],\\\"NV8\\\"],[[127488,127488],\\\"mapped\\\",[12411,12363]],[[127489,127489],\\\"mapped\\\",[12467,12467]],[[127490,127490],\\\"mapped\\\",[12469]],[[127491,127503],\\\"disallowed\\\"],[[127504,127504],\\\"mapped\\\",[25163]],[[127505,127505],\\\"mapped\\\",[23383]],[[127506,127506],\\\"mapped\\\",[21452]],[[127507,127507],\\\"mapped\\\",[12487]],[[127508,127508],\\\"mapped\\\",[20108]],[[127509,127509],\\\"mapped\\\",[22810]],[[127510,127510],\\\"mapped\\\",[35299]],[[127511,127511],\\\"mapped\\\",[22825]],[[127512,127512],\\\"mapped\\\",[20132]],[[127513,127513],\\\"mapped\\\",[26144]],[[127514,127514],\\\"mapped\\\",[28961]],[[127515,127515],\\\"mapped\\\",[26009]],[[127516,127516],\\\"mapped\\\",[21069]],[[127517,127517],\\\"mapped\\\",[24460]],[[127518,127518],\\\"mapped\\\",[20877]],[[127519,127519],\\\"mapped\\\",[26032]],[[127520,127520],\\\"mapped\\\",[21021]],[[127521,127521],\\\"mapped\\\",[32066]],[[127522,127522],\\\"mapped\\\",[29983]],[[127523,127523],\\\"mapped\\\",[36009]],[[127524,127524],\\\"mapped\\\",[22768]],[[127525,127525],\\\"mapped\\\",[21561]],[[127526,127526],\\\"mapped\\\",[28436]],[[127527,127527],\\\"mapped\\\",[25237]],[[127528,127528],\\\"mapped\\\",[25429]],[[127529,127529],\\\"mapped\\\",[19968]],[[127530,127530],\\\"mapped\\\",[19977]],[[127531,127531],\\\"mapped\\\",[36938]],[[127532,127532],\\\"mapped\\\",[24038]],[[127533,127533],\\\"mapped\\\",[20013]],[[127534,127534],\\\"mapped\\\",[21491]],[[127535,127535],\\\"mapped\\\",[25351]],[[127536,127536],\\\"mapped\\\",[36208]],[[127537,127537],\\\"mapped\\\",[25171]],[[127538,127538],\\\"mapped\\\",[31105]],[[127539,127539],\\\"mapped\\\",[31354]],[[127540,127540],\\\"mapped\\\",[21512]],[[127541,127541],\\\"mapped\\\",[28288]],[[127542,127542],\\\"mapped\\\",[26377]],[[127543,127543],\\\"mapped\\\",[26376]],[[127544,127544],\\\"mapped\\\",[30003]],[[127545,127545],\\\"mapped\\\",[21106]],[[127546,127546],\\\"mapped\\\",[21942]],[[127547,127551],\\\"disallowed\\\"],[[127552,127552],\\\"mapped\\\",[12308,26412,12309]],[[127553,127553],\\\"mapped\\\",[12308,19977,12309]],[[127554,127554],\\\"mapped\\\",[12308,20108,12309]],[[127555,127555],\\\"mapped\\\",[12308,23433,12309]],[[127556,127556],\\\"mapped\\\",[12308,28857,12309]],[[127557,127557],\\\"mapped\\\",[12308,25171,12309]],[[127558,127558],\\\"mapped\\\",[12308,30423,12309]],[[127559,127559],\\\"mapped\\\",[12308,21213,12309]],[[127560,127560],\\\"mapped\\\",[12308,25943,12309]],[[127561,127567],\\\"disallowed\\\"],[[127568,127568],\\\"mapped\\\",[24471]],[[127569,127569],\\\"mapped\\\",[21487]],[[127570,127743],\\\"disallowed\\\"],[[127744,127776],\\\"valid\\\",[],\\\"NV8\\\"],[[127777,127788],\\\"valid\\\",[],\\\"NV8\\\"],[[127789,127791],\\\"valid\\\",[],\\\"NV8\\\"],[[127792,127797],\\\"valid\\\",[],\\\"NV8\\\"],[[127798,127798],\\\"valid\\\",[],\\\"NV8\\\"],[[127799,127868],\\\"valid\\\",[],\\\"NV8\\\"],[[127869,127869],\\\"valid\\\",[],\\\"NV8\\\"],[[127870,127871],\\\"valid\\\",[],\\\"NV8\\\"],[[127872,127891],\\\"valid\\\",[],\\\"NV8\\\"],[[127892,127903],\\\"valid\\\",[],\\\"NV8\\\"],[[127904,127940],\\\"valid\\\",[],\\\"NV8\\\"],[[127941,127941],\\\"valid\\\",[],\\\"NV8\\\"],[[127942,127946],\\\"valid\\\",[],\\\"NV8\\\"],[[127947,127950],\\\"valid\\\",[],\\\"NV8\\\"],[[127951,127955],\\\"valid\\\",[],\\\"NV8\\\"],[[127956,127967],\\\"valid\\\",[],\\\"NV8\\\"],[[127968,127984],\\\"valid\\\",[],\\\"NV8\\\"],[[127985,127991],\\\"valid\\\",[],\\\"NV8\\\"],[[127992,127999],\\\"valid\\\",[],\\\"NV8\\\"],[[128000,128062],\\\"valid\\\",[],\\\"NV8\\\"],[[128063,128063],\\\"valid\\\",[],\\\"NV8\\\"],[[128064,128064],\\\"valid\\\",[],\\\"NV8\\\"],[[128065,128065],\\\"valid\\\",[],\\\"NV8\\\"],[[128066,128247],\\\"valid\\\",[],\\\"NV8\\\"],[[128248,128248],\\\"valid\\\",[],\\\"NV8\\\"],[[128249,128252],\\\"valid\\\",[],\\\"NV8\\\"],[[128253,128254],\\\"valid\\\",[],\\\"NV8\\\"],[[128255,128255],\\\"valid\\\",[],\\\"NV8\\\"],[[128256,128317],\\\"valid\\\",[],\\\"NV8\\\"],[[128318,128319],\\\"valid\\\",[],\\\"NV8\\\"],[[128320,128323],\\\"valid\\\",[],\\\"NV8\\\"],[[128324,128330],\\\"valid\\\",[],\\\"NV8\\\"],[[128331,128335],\\\"valid\\\",[],\\\"NV8\\\"],[[128336,128359],\\\"valid\\\",[],\\\"NV8\\\"],[[128360,128377],\\\"valid\\\",[],\\\"NV8\\\"],[[128378,128378],\\\"disallowed\\\"],[[128379,128419],\\\"valid\\\",[],\\\"NV8\\\"],[[128420,128420],\\\"disallowed\\\"],[[128421,128506],\\\"valid\\\",[],\\\"NV8\\\"],[[128507,128511],\\\"valid\\\",[],\\\"NV8\\\"],[[128512,128512],\\\"valid\\\",[],\\\"NV8\\\"],[[128513,128528],\\\"valid\\\",[],\\\"NV8\\\"],[[128529,128529],\\\"valid\\\",[],\\\"NV8\\\"],[[128530,128532],\\\"valid\\\",[],\\\"NV8\\\"],[[128533,128533],\\\"valid\\\",[],\\\"NV8\\\"],[[128534,128534],\\\"valid\\\",[],\\\"NV8\\\"],[[128535,128535],\\\"valid\\\",[],\\\"NV8\\\"],[[128536,128536],\\\"valid\\\",[],\\\"NV8\\\"],[[128537,128537],\\\"valid\\\",[],\\\"NV8\\\"],[[128538,128538],\\\"valid\\\",[],\\\"NV8\\\"],[[128539,128539],\\\"valid\\\",[],\\\"NV8\\\"],[[128540,128542],\\\"valid\\\",[],\\\"NV8\\\"],[[128543,128543],\\\"valid\\\",[],\\\"NV8\\\"],[[128544,128549],\\\"valid\\\",[],\\\"NV8\\\"],[[128550,128551],\\\"valid\\\",[],\\\"NV8\\\"],[[128552,128555],\\\"valid\\\",[],\\\"NV8\\\"],[[128556,128556],\\\"valid\\\",[],\\\"NV8\\\"],[[128557,128557],\\\"valid\\\",[],\\\"NV8\\\"],[[128558,128559],\\\"valid\\\",[],\\\"NV8\\\"],[[128560,128563],\\\"valid\\\",[],\\\"NV8\\\"],[[128564,128564],\\\"valid\\\",[],\\\"NV8\\\"],[[128565,128576],\\\"valid\\\",[],\\\"NV8\\\"],[[128577,128578],\\\"valid\\\",[],\\\"NV8\\\"],[[128579,128580],\\\"valid\\\",[],\\\"NV8\\\"],[[128581,128591],\\\"valid\\\",[],\\\"NV8\\\"],[[128592,128639],\\\"valid\\\",[],\\\"NV8\\\"],[[128640,128709],\\\"valid\\\",[],\\\"NV8\\\"],[[128710,128719],\\\"valid\\\",[],\\\"NV8\\\"],[[128720,128720],\\\"valid\\\",[],\\\"NV8\\\"],[[128721,128735],\\\"disallowed\\\"],[[128736,128748],\\\"valid\\\",[],\\\"NV8\\\"],[[128749,128751],\\\"disallowed\\\"],[[128752,128755],\\\"valid\\\",[],\\\"NV8\\\"],[[128756,128767],\\\"disallowed\\\"],[[128768,128883],\\\"valid\\\",[],\\\"NV8\\\"],[[128884,128895],\\\"disallowed\\\"],[[128896,128980],\\\"valid\\\",[],\\\"NV8\\\"],[[128981,129023],\\\"disallowed\\\"],[[129024,129035],\\\"valid\\\",[],\\\"NV8\\\"],[[129036,129039],\\\"disallowed\\\"],[[129040,129095],\\\"valid\\\",[],\\\"NV8\\\"],[[129096,129103],\\\"disallowed\\\"],[[129104,129113],\\\"valid\\\",[],\\\"NV8\\\"],[[129114,129119],\\\"disallowed\\\"],[[129120,129159],\\\"valid\\\",[],\\\"NV8\\\"],[[129160,129167],\\\"disallowed\\\"],[[129168,129197],\\\"valid\\\",[],\\\"NV8\\\"],[[129198,129295],\\\"disallowed\\\"],[[129296,129304],\\\"valid\\\",[],\\\"NV8\\\"],[[129305,129407],\\\"disallowed\\\"],[[129408,129412],\\\"valid\\\",[],\\\"NV8\\\"],[[129413,129471],\\\"disallowed\\\"],[[129472,129472],\\\"valid\\\",[],\\\"NV8\\\"],[[129473,131069],\\\"disallowed\\\"],[[131070,131071],\\\"disallowed\\\"],[[131072,173782],\\\"valid\\\"],[[173783,173823],\\\"disallowed\\\"],[[173824,177972],\\\"valid\\\"],[[177973,177983],\\\"disallowed\\\"],[[177984,178205],\\\"valid\\\"],[[178206,178207],\\\"disallowed\\\"],[[178208,183969],\\\"valid\\\"],[[183970,194559],\\\"disallowed\\\"],[[194560,194560],\\\"mapped\\\",[20029]],[[194561,194561],\\\"mapped\\\",[20024]],[[194562,194562],\\\"mapped\\\",[20033]],[[194563,194563],\\\"mapped\\\",[131362]],[[194564,194564],\\\"mapped\\\",[20320]],[[194565,194565],\\\"mapped\\\",[20398]],[[194566,194566],\\\"mapped\\\",[20411]],[[194567,194567],\\\"mapped\\\",[20482]],[[194568,194568],\\\"mapped\\\",[20602]],[[194569,194569],\\\"mapped\\\",[20633]],[[194570,194570],\\\"mapped\\\",[20711]],[[194571,194571],\\\"mapped\\\",[20687]],[[194572,194572],\\\"mapped\\\",[13470]],[[194573,194573],\\\"mapped\\\",[132666]],[[194574,194574],\\\"mapped\\\",[20813]],[[194575,194575],\\\"mapped\\\",[20820]],[[194576,194576],\\\"mapped\\\",[20836]],[[194577,194577],\\\"mapped\\\",[20855]],[[194578,194578],\\\"mapped\\\",[132380]],[[194579,194579],\\\"mapped\\\",[13497]],[[194580,194580],\\\"mapped\\\",[20839]],[[194581,194581],\\\"mapped\\\",[20877]],[[194582,194582],\\\"mapped\\\",[132427]],[[194583,194583],\\\"mapped\\\",[20887]],[[194584,194584],\\\"mapped\\\",[20900]],[[194585,194585],\\\"mapped\\\",[20172]],[[194586,194586],\\\"mapped\\\",[20908]],[[194587,194587],\\\"mapped\\\",[20917]],[[194588,194588],\\\"mapped\\\",[168415]],[[194589,194589],\\\"mapped\\\",[20981]],[[194590,194590],\\\"mapped\\\",[20995]],[[194591,194591],\\\"mapped\\\",[13535]],[[194592,194592],\\\"mapped\\\",[21051]],[[194593,194593],\\\"mapped\\\",[21062]],[[194594,194594],\\\"mapped\\\",[21106]],[[194595,194595],\\\"mapped\\\",[21111]],[[194596,194596],\\\"mapped\\\",[13589]],[[194597,194597],\\\"mapped\\\",[21191]],[[194598,194598],\\\"mapped\\\",[21193]],[[194599,194599],\\\"mapped\\\",[21220]],[[194600,194600],\\\"mapped\\\",[21242]],[[194601,194601],\\\"mapped\\\",[21253]],[[194602,194602],\\\"mapped\\\",[21254]],[[194603,194603],\\\"mapped\\\",[21271]],[[194604,194604],\\\"mapped\\\",[21321]],[[194605,194605],\\\"mapped\\\",[21329]],[[194606,194606],\\\"mapped\\\",[21338]],[[194607,194607],\\\"mapped\\\",[21363]],[[194608,194608],\\\"mapped\\\",[21373]],[[194609,194611],\\\"mapped\\\",[21375]],[[194612,194612],\\\"mapped\\\",[133676]],[[194613,194613],\\\"mapped\\\",[28784]],[[194614,194614],\\\"mapped\\\",[21450]],[[194615,194615],\\\"mapped\\\",[21471]],[[194616,194616],\\\"mapped\\\",[133987]],[[194617,194617],\\\"mapped\\\",[21483]],[[194618,194618],\\\"mapped\\\",[21489]],[[194619,194619],\\\"mapped\\\",[21510]],[[194620,194620],\\\"mapped\\\",[21662]],[[194621,194621],\\\"mapped\\\",[21560]],[[194622,194622],\\\"mapped\\\",[21576]],[[194623,194623],\\\"mapped\\\",[21608]],[[194624,194624],\\\"mapped\\\",[21666]],[[194625,194625],\\\"mapped\\\",[21750]],[[194626,194626],\\\"mapped\\\",[21776]],[[194627,194627],\\\"mapped\\\",[21843]],[[194628,194628],\\\"mapped\\\",[21859]],[[194629,194630],\\\"mapped\\\",[21892]],[[194631,194631],\\\"mapped\\\",[21913]],[[194632,194632],\\\"mapped\\\",[21931]],[[194633,194633],\\\"mapped\\\",[21939]],[[194634,194634],\\\"mapped\\\",[21954]],[[194635,194635],\\\"mapped\\\",[22294]],[[194636,194636],\\\"mapped\\\",[22022]],[[194637,194637],\\\"mapped\\\",[22295]],[[194638,194638],\\\"mapped\\\",[22097]],[[194639,194639],\\\"mapped\\\",[22132]],[[194640,194640],\\\"mapped\\\",[20999]],[[194641,194641],\\\"mapped\\\",[22766]],[[194642,194642],\\\"mapped\\\",[22478]],[[194643,194643],\\\"mapped\\\",[22516]],[[194644,194644],\\\"mapped\\\",[22541]],[[194645,194645],\\\"mapped\\\",[22411]],[[194646,194646],\\\"mapped\\\",[22578]],[[194647,194647],\\\"mapped\\\",[22577]],[[194648,194648],\\\"mapped\\\",[22700]],[[194649,194649],\\\"mapped\\\",[136420]],[[194650,194650],\\\"mapped\\\",[22770]],[[194651,194651],\\\"mapped\\\",[22775]],[[194652,194652],\\\"mapped\\\",[22790]],[[194653,194653],\\\"mapped\\\",[22810]],[[194654,194654],\\\"mapped\\\",[22818]],[[194655,194655],\\\"mapped\\\",[22882]],[[194656,194656],\\\"mapped\\\",[136872]],[[194657,194657],\\\"mapped\\\",[136938]],[[194658,194658],\\\"mapped\\\",[23020]],[[194659,194659],\\\"mapped\\\",[23067]],[[194660,194660],\\\"mapped\\\",[23079]],[[194661,194661],\\\"mapped\\\",[23000]],[[194662,194662],\\\"mapped\\\",[23142]],[[194663,194663],\\\"mapped\\\",[14062]],[[194664,194664],\\\"disallowed\\\"],[[194665,194665],\\\"mapped\\\",[23304]],[[194666,194667],\\\"mapped\\\",[23358]],[[194668,194668],\\\"mapped\\\",[137672]],[[194669,194669],\\\"mapped\\\",[23491]],[[194670,194670],\\\"mapped\\\",[23512]],[[194671,194671],\\\"mapped\\\",[23527]],[[194672,194672],\\\"mapped\\\",[23539]],[[194673,194673],\\\"mapped\\\",[138008]],[[194674,194674],\\\"mapped\\\",[23551]],[[194675,194675],\\\"mapped\\\",[23558]],[[194676,194676],\\\"disallowed\\\"],[[194677,194677],\\\"mapped\\\",[23586]],[[194678,194678],\\\"mapped\\\",[14209]],[[194679,194679],\\\"mapped\\\",[23648]],[[194680,194680],\\\"mapped\\\",[23662]],[[194681,194681],\\\"mapped\\\",[23744]],[[194682,194682],\\\"mapped\\\",[23693]],[[194683,194683],\\\"mapped\\\",[138724]],[[194684,194684],\\\"mapped\\\",[23875]],[[194685,194685],\\\"mapped\\\",[138726]],[[194686,194686],\\\"mapped\\\",[23918]],[[194687,194687],\\\"mapped\\\",[23915]],[[194688,194688],\\\"mapped\\\",[23932]],[[194689,194689],\\\"mapped\\\",[24033]],[[194690,194690],\\\"mapped\\\",[24034]],[[194691,194691],\\\"mapped\\\",[14383]],[[194692,194692],\\\"mapped\\\",[24061]],[[194693,194693],\\\"mapped\\\",[24104]],[[194694,194694],\\\"mapped\\\",[24125]],[[194695,194695],\\\"mapped\\\",[24169]],[[194696,194696],\\\"mapped\\\",[14434]],[[194697,194697],\\\"mapped\\\",[139651]],[[194698,194698],\\\"mapped\\\",[14460]],[[194699,194699],\\\"mapped\\\",[24240]],[[194700,194700],\\\"mapped\\\",[24243]],[[194701,194701],\\\"mapped\\\",[24246]],[[194702,194702],\\\"mapped\\\",[24266]],[[194703,194703],\\\"mapped\\\",[172946]],[[194704,194704],\\\"mapped\\\",[24318]],[[194705,194706],\\\"mapped\\\",[140081]],[[194707,194707],\\\"mapped\\\",[33281]],[[194708,194709],\\\"mapped\\\",[24354]],[[194710,194710],\\\"mapped\\\",[14535]],[[194711,194711],\\\"mapped\\\",[144056]],[[194712,194712],\\\"mapped\\\",[156122]],[[194713,194713],\\\"mapped\\\",[24418]],[[194714,194714],\\\"mapped\\\",[24427]],[[194715,194715],\\\"mapped\\\",[14563]],[[194716,194716],\\\"mapped\\\",[24474]],[[194717,194717],\\\"mapped\\\",[24525]],[[194718,194718],\\\"mapped\\\",[24535]],[[194719,194719],\\\"mapped\\\",[24569]],[[194720,194720],\\\"mapped\\\",[24705]],[[194721,194721],\\\"mapped\\\",[14650]],[[194722,194722],\\\"mapped\\\",[14620]],[[194723,194723],\\\"mapped\\\",[24724]],[[194724,194724],\\\"mapped\\\",[141012]],[[194725,194725],\\\"mapped\\\",[24775]],[[194726,194726],\\\"mapped\\\",[24904]],[[194727,194727],\\\"mapped\\\",[24908]],[[194728,194728],\\\"mapped\\\",[24910]],[[194729,194729],\\\"mapped\\\",[24908]],[[194730,194730],\\\"mapped\\\",[24954]],[[194731,194731],\\\"mapped\\\",[24974]],[[194732,194732],\\\"mapped\\\",[25010]],[[194733,194733],\\\"mapped\\\",[24996]],[[194734,194734],\\\"mapped\\\",[25007]],[[194735,194735],\\\"mapped\\\",[25054]],[[194736,194736],\\\"mapped\\\",[25074]],[[194737,194737],\\\"mapped\\\",[25078]],[[194738,194738],\\\"mapped\\\",[25104]],[[194739,194739],\\\"mapped\\\",[25115]],[[194740,194740],\\\"mapped\\\",[25181]],[[194741,194741],\\\"mapped\\\",[25265]],[[194742,194742],\\\"mapped\\\",[25300]],[[194743,194743],\\\"mapped\\\",[25424]],[[194744,194744],\\\"mapped\\\",[142092]],[[194745,194745],\\\"mapped\\\",[25405]],[[194746,194746],\\\"mapped\\\",[25340]],[[194747,194747],\\\"mapped\\\",[25448]],[[194748,194748],\\\"mapped\\\",[25475]],[[194749,194749],\\\"mapped\\\",[25572]],[[194750,194750],\\\"mapped\\\",[142321]],[[194751,194751],\\\"mapped\\\",[25634]],[[194752,194752],\\\"mapped\\\",[25541]],[[194753,194753],\\\"mapped\\\",[25513]],[[194754,194754],\\\"mapped\\\",[14894]],[[194755,194755],\\\"mapped\\\",[25705]],[[194756,194756],\\\"mapped\\\",[25726]],[[194757,194757],\\\"mapped\\\",[25757]],[[194758,194758],\\\"mapped\\\",[25719]],[[194759,194759],\\\"mapped\\\",[14956]],[[194760,194760],\\\"mapped\\\",[25935]],[[194761,194761],\\\"mapped\\\",[25964]],[[194762,194762],\\\"mapped\\\",[143370]],[[194763,194763],\\\"mapped\\\",[26083]],[[194764,194764],\\\"mapped\\\",[26360]],[[194765,194765],\\\"mapped\\\",[26185]],[[194766,194766],\\\"mapped\\\",[15129]],[[194767,194767],\\\"mapped\\\",[26257]],[[194768,194768],\\\"mapped\\\",[15112]],[[194769,194769],\\\"mapped\\\",[15076]],[[194770,194770],\\\"mapped\\\",[20882]],[[194771,194771],\\\"mapped\\\",[20885]],[[194772,194772],\\\"mapped\\\",[26368]],[[194773,194773],\\\"mapped\\\",[26268]],[[194774,194774],\\\"mapped\\\",[32941]],[[194775,194775],\\\"mapped\\\",[17369]],[[194776,194776],\\\"mapped\\\",[26391]],[[194777,194777],\\\"mapped\\\",[26395]],[[194778,194778],\\\"mapped\\\",[26401]],[[194779,194779],\\\"mapped\\\",[26462]],[[194780,194780],\\\"mapped\\\",[26451]],[[194781,194781],\\\"mapped\\\",[144323]],[[194782,194782],\\\"mapped\\\",[15177]],[[194783,194783],\\\"mapped\\\",[26618]],[[194784,194784],\\\"mapped\\\",[26501]],[[194785,194785],\\\"mapped\\\",[26706]],[[194786,194786],\\\"mapped\\\",[26757]],[[194787,194787],\\\"mapped\\\",[144493]],[[194788,194788],\\\"mapped\\\",[26766]],[[194789,194789],\\\"mapped\\\",[26655]],[[194790,194790],\\\"mapped\\\",[26900]],[[194791,194791],\\\"mapped\\\",[15261]],[[194792,194792],\\\"mapped\\\",[26946]],[[194793,194793],\\\"mapped\\\",[27043]],[[194794,194794],\\\"mapped\\\",[27114]],[[194795,194795],\\\"mapped\\\",[27304]],[[194796,194796],\\\"mapped\\\",[145059]],[[194797,194797],\\\"mapped\\\",[27355]],[[194798,194798],\\\"mapped\\\",[15384]],[[194799,194799],\\\"mapped\\\",[27425]],[[194800,194800],\\\"mapped\\\",[145575]],[[194801,194801],\\\"mapped\\\",[27476]],[[194802,194802],\\\"mapped\\\",[15438]],[[194803,194803],\\\"mapped\\\",[27506]],[[194804,194804],\\\"mapped\\\",[27551]],[[194805,194805],\\\"mapped\\\",[27578]],[[194806,194806],\\\"mapped\\\",[27579]],[[194807,194807],\\\"mapped\\\",[146061]],[[194808,194808],\\\"mapped\\\",[138507]],[[194809,194809],\\\"mapped\\\",[146170]],[[194810,194810],\\\"mapped\\\",[27726]],[[194811,194811],\\\"mapped\\\",[146620]],[[194812,194812],\\\"mapped\\\",[27839]],[[194813,194813],\\\"mapped\\\",[27853]],[[194814,194814],\\\"mapped\\\",[27751]],[[194815,194815],\\\"mapped\\\",[27926]],[[194816,194816],\\\"mapped\\\",[27966]],[[194817,194817],\\\"mapped\\\",[28023]],[[194818,194818],\\\"mapped\\\",[27969]],[[194819,194819],\\\"mapped\\\",[28009]],[[194820,194820],\\\"mapped\\\",[28024]],[[194821,194821],\\\"mapped\\\",[28037]],[[194822,194822],\\\"mapped\\\",[146718]],[[194823,194823],\\\"mapped\\\",[27956]],[[194824,194824],\\\"mapped\\\",[28207]],[[194825,194825],\\\"mapped\\\",[28270]],[[194826,194826],\\\"mapped\\\",[15667]],[[194827,194827],\\\"mapped\\\",[28363]],[[194828,194828],\\\"mapped\\\",[28359]],[[194829,194829],\\\"mapped\\\",[147153]],[[194830,194830],\\\"mapped\\\",[28153]],[[194831,194831],\\\"mapped\\\",[28526]],[[194832,194832],\\\"mapped\\\",[147294]],[[194833,194833],\\\"mapped\\\",[147342]],[[194834,194834],\\\"mapped\\\",[28614]],[[194835,194835],\\\"mapped\\\",[28729]],[[194836,194836],\\\"mapped\\\",[28702]],[[194837,194837],\\\"mapped\\\",[28699]],[[194838,194838],\\\"mapped\\\",[15766]],[[194839,194839],\\\"mapped\\\",[28746]],[[194840,194840],\\\"mapped\\\",[28797]],[[194841,194841],\\\"mapped\\\",[28791]],[[194842,194842],\\\"mapped\\\",[28845]],[[194843,194843],\\\"mapped\\\",[132389]],[[194844,194844],\\\"mapped\\\",[28997]],[[194845,194845],\\\"mapped\\\",[148067]],[[194846,194846],\\\"mapped\\\",[29084]],[[194847,194847],\\\"disallowed\\\"],[[194848,194848],\\\"mapped\\\",[29224]],[[194849,194849],\\\"mapped\\\",[29237]],[[194850,194850],\\\"mapped\\\",[29264]],[[194851,194851],\\\"mapped\\\",[149000]],[[194852,194852],\\\"mapped\\\",[29312]],[[194853,194853],\\\"mapped\\\",[29333]],[[194854,194854],\\\"mapped\\\",[149301]],[[194855,194855],\\\"mapped\\\",[149524]],[[194856,194856],\\\"mapped\\\",[29562]],[[194857,194857],\\\"mapped\\\",[29579]],[[194858,194858],\\\"mapped\\\",[16044]],[[194859,194859],\\\"mapped\\\",[29605]],[[194860,194861],\\\"mapped\\\",[16056]],[[194862,194862],\\\"mapped\\\",[29767]],[[194863,194863],\\\"mapped\\\",[29788]],[[194864,194864],\\\"mapped\\\",[29809]],[[194865,194865],\\\"mapped\\\",[29829]],[[194866,194866],\\\"mapped\\\",[29898]],[[194867,194867],\\\"mapped\\\",[16155]],[[194868,194868],\\\"mapped\\\",[29988]],[[194869,194869],\\\"mapped\\\",[150582]],[[194870,194870],\\\"mapped\\\",[30014]],[[194871,194871],\\\"mapped\\\",[150674]],[[194872,194872],\\\"mapped\\\",[30064]],[[194873,194873],\\\"mapped\\\",[139679]],[[194874,194874],\\\"mapped\\\",[30224]],[[194875,194875],\\\"mapped\\\",[151457]],[[194876,194876],\\\"mapped\\\",[151480]],[[194877,194877],\\\"mapped\\\",[151620]],[[194878,194878],\\\"mapped\\\",[16380]],[[194879,194879],\\\"mapped\\\",[16392]],[[194880,194880],\\\"mapped\\\",[30452]],[[194881,194881],\\\"mapped\\\",[151795]],[[194882,194882],\\\"mapped\\\",[151794]],[[194883,194883],\\\"mapped\\\",[151833]],[[194884,194884],\\\"mapped\\\",[151859]],[[194885,194885],\\\"mapped\\\",[30494]],[[194886,194887],\\\"mapped\\\",[30495]],[[194888,194888],\\\"mapped\\\",[30538]],[[194889,194889],\\\"mapped\\\",[16441]],[[194890,194890],\\\"mapped\\\",[30603]],[[194891,194891],\\\"mapped\\\",[16454]],[[194892,194892],\\\"mapped\\\",[16534]],[[194893,194893],\\\"mapped\\\",[152605]],[[194894,194894],\\\"mapped\\\",[30798]],[[194895,194895],\\\"mapped\\\",[30860]],[[194896,194896],\\\"mapped\\\",[30924]],[[194897,194897],\\\"mapped\\\",[16611]],[[194898,194898],\\\"mapped\\\",[153126]],[[194899,194899],\\\"mapped\\\",[31062]],[[194900,194900],\\\"mapped\\\",[153242]],[[194901,194901],\\\"mapped\\\",[153285]],[[194902,194902],\\\"mapped\\\",[31119]],[[194903,194903],\\\"mapped\\\",[31211]],[[194904,194904],\\\"mapped\\\",[16687]],[[194905,194905],\\\"mapped\\\",[31296]],[[194906,194906],\\\"mapped\\\",[31306]],[[194907,194907],\\\"mapped\\\",[31311]],[[194908,194908],\\\"mapped\\\",[153980]],[[194909,194910],\\\"mapped\\\",[154279]],[[194911,194911],\\\"disallowed\\\"],[[194912,194912],\\\"mapped\\\",[16898]],[[194913,194913],\\\"mapped\\\",[154539]],[[194914,194914],\\\"mapped\\\",[31686]],[[194915,194915],\\\"mapped\\\",[31689]],[[194916,194916],\\\"mapped\\\",[16935]],[[194917,194917],\\\"mapped\\\",[154752]],[[194918,194918],\\\"mapped\\\",[31954]],[[194919,194919],\\\"mapped\\\",[17056]],[[194920,194920],\\\"mapped\\\",[31976]],[[194921,194921],\\\"mapped\\\",[31971]],[[194922,194922],\\\"mapped\\\",[32000]],[[194923,194923],\\\"mapped\\\",[155526]],[[194924,194924],\\\"mapped\\\",[32099]],[[194925,194925],\\\"mapped\\\",[17153]],[[194926,194926],\\\"mapped\\\",[32199]],[[194927,194927],\\\"mapped\\\",[32258]],[[194928,194928],\\\"mapped\\\",[32325]],[[194929,194929],\\\"mapped\\\",[17204]],[[194930,194930],\\\"mapped\\\",[156200]],[[194931,194931],\\\"mapped\\\",[156231]],[[194932,194932],\\\"mapped\\\",[17241]],[[194933,194933],\\\"mapped\\\",[156377]],[[194934,194934],\\\"mapped\\\",[32634]],[[194935,194935],\\\"mapped\\\",[156478]],[[194936,194936],\\\"mapped\\\",[32661]],[[194937,194937],\\\"mapped\\\",[32762]],[[194938,194938],\\\"mapped\\\",[32773]],[[194939,194939],\\\"mapped\\\",[156890]],[[194940,194940],\\\"mapped\\\",[156963]],[[194941,194941],\\\"mapped\\\",[32864]],[[194942,194942],\\\"mapped\\\",[157096]],[[194943,194943],\\\"mapped\\\",[32880]],[[194944,194944],\\\"mapped\\\",[144223]],[[194945,194945],\\\"mapped\\\",[17365]],[[194946,194946],\\\"mapped\\\",[32946]],[[194947,194947],\\\"mapped\\\",[33027]],[[194948,194948],\\\"mapped\\\",[17419]],[[194949,194949],\\\"mapped\\\",[33086]],[[194950,194950],\\\"mapped\\\",[23221]],[[194951,194951],\\\"mapped\\\",[157607]],[[194952,194952],\\\"mapped\\\",[157621]],[[194953,194953],\\\"mapped\\\",[144275]],[[194954,194954],\\\"mapped\\\",[144284]],[[194955,194955],\\\"mapped\\\",[33281]],[[194956,194956],\\\"mapped\\\",[33284]],[[194957,194957],\\\"mapped\\\",[36766]],[[194958,194958],\\\"mapped\\\",[17515]],[[194959,194959],\\\"mapped\\\",[33425]],[[194960,194960],\\\"mapped\\\",[33419]],[[194961,194961],\\\"mapped\\\",[33437]],[[194962,194962],\\\"mapped\\\",[21171]],[[194963,194963],\\\"mapped\\\",[33457]],[[194964,194964],\\\"mapped\\\",[33459]],[[194965,194965],\\\"mapped\\\",[33469]],[[194966,194966],\\\"mapped\\\",[33510]],[[194967,194967],\\\"mapped\\\",[158524]],[[194968,194968],\\\"mapped\\\",[33509]],[[194969,194969],\\\"mapped\\\",[33565]],[[194970,194970],\\\"mapped\\\",[33635]],[[194971,194971],\\\"mapped\\\",[33709]],[[194972,194972],\\\"mapped\\\",[33571]],[[194973,194973],\\\"mapped\\\",[33725]],[[194974,194974],\\\"mapped\\\",[33767]],[[194975,194975],\\\"mapped\\\",[33879]],[[194976,194976],\\\"mapped\\\",[33619]],[[194977,194977],\\\"mapped\\\",[33738]],[[194978,194978],\\\"mapped\\\",[33740]],[[194979,194979],\\\"mapped\\\",[33756]],[[194980,194980],\\\"mapped\\\",[158774]],[[194981,194981],\\\"mapped\\\",[159083]],[[194982,194982],\\\"mapped\\\",[158933]],[[194983,194983],\\\"mapped\\\",[17707]],[[194984,194984],\\\"mapped\\\",[34033]],[[194985,194985],\\\"mapped\\\",[34035]],[[194986,194986],\\\"mapped\\\",[34070]],[[194987,194987],\\\"mapped\\\",[160714]],[[194988,194988],\\\"mapped\\\",[34148]],[[194989,194989],\\\"mapped\\\",[159532]],[[194990,194990],\\\"mapped\\\",[17757]],[[194991,194991],\\\"mapped\\\",[17761]],[[194992,194992],\\\"mapped\\\",[159665]],[[194993,194993],\\\"mapped\\\",[159954]],[[194994,194994],\\\"mapped\\\",[17771]],[[194995,194995],\\\"mapped\\\",[34384]],[[194996,194996],\\\"mapped\\\",[34396]],[[194997,194997],\\\"mapped\\\",[34407]],[[194998,194998],\\\"mapped\\\",[34409]],[[194999,194999],\\\"mapped\\\",[34473]],[[195000,195000],\\\"mapped\\\",[34440]],[[195001,195001],\\\"mapped\\\",[34574]],[[195002,195002],\\\"mapped\\\",[34530]],[[195003,195003],\\\"mapped\\\",[34681]],[[195004,195004],\\\"mapped\\\",[34600]],[[195005,195005],\\\"mapped\\\",[34667]],[[195006,195006],\\\"mapped\\\",[34694]],[[195007,195007],\\\"disallowed\\\"],[[195008,195008],\\\"mapped\\\",[34785]],[[195009,195009],\\\"mapped\\\",[34817]],[[195010,195010],\\\"mapped\\\",[17913]],[[195011,195011],\\\"mapped\\\",[34912]],[[195012,195012],\\\"mapped\\\",[34915]],[[195013,195013],\\\"mapped\\\",[161383]],[[195014,195014],\\\"mapped\\\",[35031]],[[195015,195015],\\\"mapped\\\",[35038]],[[195016,195016],\\\"mapped\\\",[17973]],[[195017,195017],\\\"mapped\\\",[35066]],[[195018,195018],\\\"mapped\\\",[13499]],[[195019,195019],\\\"mapped\\\",[161966]],[[195020,195020],\\\"mapped\\\",[162150]],[[195021,195021],\\\"mapped\\\",[18110]],[[195022,195022],\\\"mapped\\\",[18119]],[[195023,195023],\\\"mapped\\\",[35488]],[[195024,195024],\\\"mapped\\\",[35565]],[[195025,195025],\\\"mapped\\\",[35722]],[[195026,195026],\\\"mapped\\\",[35925]],[[195027,195027],\\\"mapped\\\",[162984]],[[195028,195028],\\\"mapped\\\",[36011]],[[195029,195029],\\\"mapped\\\",[36033]],[[195030,195030],\\\"mapped\\\",[36123]],[[195031,195031],\\\"mapped\\\",[36215]],[[195032,195032],\\\"mapped\\\",[163631]],[[195033,195033],\\\"mapped\\\",[133124]],[[195034,195034],\\\"mapped\\\",[36299]],[[195035,195035],\\\"mapped\\\",[36284]],[[195036,195036],\\\"mapped\\\",[36336]],[[195037,195037],\\\"mapped\\\",[133342]],[[195038,195038],\\\"mapped\\\",[36564]],[[195039,195039],\\\"mapped\\\",[36664]],[[195040,195040],\\\"mapped\\\",[165330]],[[195041,195041],\\\"mapped\\\",[165357]],[[195042,195042],\\\"mapped\\\",[37012]],[[195043,195043],\\\"mapped\\\",[37105]],[[195044,195044],\\\"mapped\\\",[37137]],[[195045,195045],\\\"mapped\\\",[165678]],[[195046,195046],\\\"mapped\\\",[37147]],[[195047,195047],\\\"mapped\\\",[37432]],[[195048,195048],\\\"mapped\\\",[37591]],[[195049,195049],\\\"mapped\\\",[37592]],[[195050,195050],\\\"mapped\\\",[37500]],[[195051,195051],\\\"mapped\\\",[37881]],[[195052,195052],\\\"mapped\\\",[37909]],[[195053,195053],\\\"mapped\\\",[166906]],[[195054,195054],\\\"mapped\\\",[38283]],[[195055,195055],\\\"mapped\\\",[18837]],[[195056,195056],\\\"mapped\\\",[38327]],[[195057,195057],\\\"mapped\\\",[167287]],[[195058,195058],\\\"mapped\\\",[18918]],[[195059,195059],\\\"mapped\\\",[38595]],[[195060,195060],\\\"mapped\\\",[23986]],[[195061,195061],\\\"mapped\\\",[38691]],[[195062,195062],\\\"mapped\\\",[168261]],[[195063,195063],\\\"mapped\\\",[168474]],[[195064,195064],\\\"mapped\\\",[19054]],[[195065,195065],\\\"mapped\\\",[19062]],[[195066,195066],\\\"mapped\\\",[38880]],[[195067,195067],\\\"mapped\\\",[168970]],[[195068,195068],\\\"mapped\\\",[19122]],[[195069,195069],\\\"mapped\\\",[169110]],[[195070,195071],\\\"mapped\\\",[38923]],[[195072,195072],\\\"mapped\\\",[38953]],[[195073,195073],\\\"mapped\\\",[169398]],[[195074,195074],\\\"mapped\\\",[39138]],[[195075,195075],\\\"mapped\\\",[19251]],[[195076,195076],\\\"mapped\\\",[39209]],[[195077,195077],\\\"mapped\\\",[39335]],[[195078,195078],\\\"mapped\\\",[39362]],[[195079,195079],\\\"mapped\\\",[39422]],[[195080,195080],\\\"mapped\\\",[19406]],[[195081,195081],\\\"mapped\\\",[170800]],[[195082,195082],\\\"mapped\\\",[39698]],[[195083,195083],\\\"mapped\\\",[40000]],[[195084,195084],\\\"mapped\\\",[40189]],[[195085,195085],\\\"mapped\\\",[19662]],[[195086,195086],\\\"mapped\\\",[19693]],[[195087,195087],\\\"mapped\\\",[40295]],[[195088,195088],\\\"mapped\\\",[172238]],[[195089,195089],\\\"mapped\\\",[19704]],[[195090,195090],\\\"mapped\\\",[172293]],[[195091,195091],\\\"mapped\\\",[172558]],[[195092,195092],\\\"mapped\\\",[172689]],[[195093,195093],\\\"mapped\\\",[40635]],[[195094,195094],\\\"mapped\\\",[19798]],[[195095,195095],\\\"mapped\\\",[40697]],[[195096,195096],\\\"mapped\\\",[40702]],[[195097,195097],\\\"mapped\\\",[40709]],[[195098,195098],\\\"mapped\\\",[40719]],[[195099,195099],\\\"mapped\\\",[40726]],[[195100,195100],\\\"mapped\\\",[40763]],[[195101,195101],\\\"mapped\\\",[173568]],[[195102,196605],\\\"disallowed\\\"],[[196606,196607],\\\"disallowed\\\"],[[196608,262141],\\\"disallowed\\\"],[[262142,262143],\\\"disallowed\\\"],[[262144,327677],\\\"disallowed\\\"],[[327678,327679],\\\"disallowed\\\"],[[327680,393213],\\\"disallowed\\\"],[[393214,393215],\\\"disallowed\\\"],[[393216,458749],\\\"disallowed\\\"],[[458750,458751],\\\"disallowed\\\"],[[458752,524285],\\\"disallowed\\\"],[[524286,524287],\\\"disallowed\\\"],[[524288,589821],\\\"disallowed\\\"],[[589822,589823],\\\"disallowed\\\"],[[589824,655357],\\\"disallowed\\\"],[[655358,655359],\\\"disallowed\\\"],[[655360,720893],\\\"disallowed\\\"],[[720894,720895],\\\"disallowed\\\"],[[720896,786429],\\\"disallowed\\\"],[[786430,786431],\\\"disallowed\\\"],[[786432,851965],\\\"disallowed\\\"],[[851966,851967],\\\"disallowed\\\"],[[851968,917501],\\\"disallowed\\\"],[[917502,917503],\\\"disallowed\\\"],[[917504,917504],\\\"disallowed\\\"],[[917505,917505],\\\"disallowed\\\"],[[917506,917535],\\\"disallowed\\\"],[[917536,917631],\\\"disallowed\\\"],[[917632,917759],\\\"disallowed\\\"],[[917760,917999],\\\"ignored\\\"],[[918000,983037],\\\"disallowed\\\"],[[983038,983039],\\\"disallowed\\\"],[[983040,1048573],\\\"disallowed\\\"],[[1048574,1048575],\\\"disallowed\\\"],[[1048576,1114109],\\\"disallowed\\\"],[[1114110,1114111],\\\"disallowed\\\"]]\");\n\n/***/ }),\n\n/***/ 2357:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"assert\");\n\n/***/ }),\n\n/***/ 8614:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"events\");\n\n/***/ }),\n\n/***/ 5747:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"fs\");\n\n/***/ }),\n\n/***/ 8605:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"http\");\n\n/***/ }),\n\n/***/ 7211:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"https\");\n\n/***/ }),\n\n/***/ 1631:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"net\");\n\n/***/ }),\n\n/***/ 2087:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"os\");\n\n/***/ }),\n\n/***/ 5622:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"path\");\n\n/***/ }),\n\n/***/ 4213:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"punycode\");\n\n/***/ }),\n\n/***/ 2413:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"stream\");\n\n/***/ }),\n\n/***/ 4016:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"tls\");\n\n/***/ }),\n\n/***/ 8835:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"url\");\n\n/***/ }),\n\n/***/ 1669:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"util\");\n\n/***/ }),\n\n/***/ 8761:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"zlib\");\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\tvar threw = true;\n/******/ \t\ttry {\n/******/ \t\t\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/ \t\t\tthrew = false;\n/******/ \t\t} finally {\n/******/ \t\t\tif(threw) delete __webpack_module_cache__[moduleId];\n/******/ \t\t}\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat */\n/******/ \t\n/******/ \t__webpack_require__.ab = __dirname + \"/\";/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(2932);\n/******/ })()\n;"
  },
  {
    "path": "pkg/runner/testdata/actions/node16/index.js",
    "content": "const core = require('@actions/core');\nconst github = require('@actions/github');\n\ntry {\n  // `who-to-greet` input defined in action metadata file\n  const nameToGreet = core.getInput('who-to-greet');\n  console.log(`Hello ${nameToGreet}!`);\n  const time = (new Date()).toTimeString();\n  core.setOutput(\"time\", time);\n  // Get the JSON webhook payload for the event that triggered the workflow\n  const payload = JSON.stringify(github.context.payload, undefined, 2)\n  console.log(`The event payload: ${payload}`);\n} catch (error) {\n  core.setFailed(error.message);\n}"
  },
  {
    "path": "pkg/runner/testdata/actions/node16/package.json",
    "content": "{\n  \"name\": \"node16\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"build\": \"ncc build index.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"@actions/core\": \"^1.2.6\",\n    \"@actions/github\": \"^4.0.0\"\n  },\n  \"devDependencies\": {\n    \"@vercel/ncc\": \"^0.24.1\"\n  },\n  \"engines\": {\n    \"node\": \">=16\"\n  }\n}\n"
  },
  {
    "path": "pkg/runner/testdata/actions/node20/README.md",
    "content": "### Updating\n\nIf an update to this app is required, it must be done manually via `npm run-script build` since the `node_modules` are not shared.\n"
  },
  {
    "path": "pkg/runner/testdata/actions/node20/action.yml",
    "content": "name: 'Hello World'\ndescription: 'Greet someone and record the time'\ninputs:\n  who-to-greet:  # id of input\n    description: 'Who to greet'\n    required: true\n    default: 'World'\noutputs:\n  time: # id of output\n    description: 'The time we greeted you'\nruns:\n  using: 'node20'\n  main: 'dist/index.js'\n"
  },
  {
    "path": "pkg/runner/testdata/actions/node20/dist/index.js",
    "content": "module.exports =\n/******/ (() => { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 2932:\n/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {\n\nconst core = __webpack_require__(2186);\nconst github = __webpack_require__(5438);\n\ntry {\n  // `who-to-greet` input defined in action metadata file\n  const nameToGreet = core.getInput('who-to-greet');\n  console.log(`Hello ${nameToGreet}!`);\n  const time = (new Date()).toTimeString();\n  core.setOutput(\"time\", time);\n  // Get the JSON webhook payload for the event that triggered the workflow\n  const payload = JSON.stringify(github.context.payload, undefined, 2)\n  console.log(`The event payload: ${payload}`);\n} catch (error) {\n  core.setFailed(error.message);\n}\n\n/***/ }),\n\n/***/ 7351:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.issue = exports.issueCommand = void 0;\nconst os = __importStar(__webpack_require__(2087));\nconst utils_1 = __webpack_require__(5278);\n/**\n * Commands\n *\n * Command Format:\n *   ::name key=value,key=value::message\n *\n * Examples:\n *   ::warning::This is the message\n *   ::set-env name=MY_VAR::some value\n */\nfunction issueCommand(command, properties, message) {\n    const cmd = new Command(command, properties, message);\n    process.stdout.write(cmd.toString() + os.EOL);\n}\nexports.issueCommand = issueCommand;\nfunction issue(name, message = '') {\n    issueCommand(name, {}, message);\n}\nexports.issue = issue;\nconst CMD_STRING = '::';\nclass Command {\n    constructor(command, properties, message) {\n        if (!command) {\n            command = 'missing.command';\n        }\n        this.command = command;\n        this.properties = properties;\n        this.message = message;\n    }\n    toString() {\n        let cmdStr = CMD_STRING + this.command;\n        if (this.properties && Object.keys(this.properties).length > 0) {\n            cmdStr += ' ';\n            let first = true;\n            for (const key in this.properties) {\n                if (this.properties.hasOwnProperty(key)) {\n                    const val = this.properties[key];\n                    if (val) {\n                        if (first) {\n                            first = false;\n                        }\n                        else {\n                            cmdStr += ',';\n                        }\n                        cmdStr += `${key}=${escapeProperty(val)}`;\n                    }\n                }\n            }\n        }\n        cmdStr += `${CMD_STRING}${escapeData(this.message)}`;\n        return cmdStr;\n    }\n}\nfunction escapeData(s) {\n    return utils_1.toCommandValue(s)\n        .replace(/%/g, '%25')\n        .replace(/\\r/g, '%0D')\n        .replace(/\\n/g, '%0A');\n}\nfunction escapeProperty(s) {\n    return utils_1.toCommandValue(s)\n        .replace(/%/g, '%25')\n        .replace(/\\r/g, '%0D')\n        .replace(/\\n/g, '%0A')\n        .replace(/:/g, '%3A')\n        .replace(/,/g, '%2C');\n}\n//# sourceMappingURL=command.js.map\n\n/***/ }),\n\n/***/ 2186:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0;\nconst command_1 = __webpack_require__(7351);\nconst file_command_1 = __webpack_require__(717);\nconst utils_1 = __webpack_require__(5278);\nconst os = __importStar(__webpack_require__(2087));\nconst path = __importStar(__webpack_require__(5622));\nconst oidc_utils_1 = __webpack_require__(8041);\n/**\n * The code to exit an action\n */\nvar ExitCode;\n(function (ExitCode) {\n    /**\n     * A code indicating that the action was successful\n     */\n    ExitCode[ExitCode[\"Success\"] = 0] = \"Success\";\n    /**\n     * A code indicating that the action was a failure\n     */\n    ExitCode[ExitCode[\"Failure\"] = 1] = \"Failure\";\n})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));\n//-----------------------------------------------------------------------\n// Variables\n//-----------------------------------------------------------------------\n/**\n * Sets env variable for this action and future actions in the job\n * @param name the name of the variable to set\n * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction exportVariable(name, val) {\n    const convertedVal = utils_1.toCommandValue(val);\n    process.env[name] = convertedVal;\n    const filePath = process.env['GITHUB_ENV'] || '';\n    if (filePath) {\n        const delimiter = '_GitHubActionsFileCommandDelimeter_';\n        const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;\n        file_command_1.issueCommand('ENV', commandValue);\n    }\n    else {\n        command_1.issueCommand('set-env', { name }, convertedVal);\n    }\n}\nexports.exportVariable = exportVariable;\n/**\n * Registers a secret which will get masked from logs\n * @param secret value of the secret\n */\nfunction setSecret(secret) {\n    command_1.issueCommand('add-mask', {}, secret);\n}\nexports.setSecret = setSecret;\n/**\n * Prepends inputPath to the PATH (for this action and future actions)\n * @param inputPath\n */\nfunction addPath(inputPath) {\n    const filePath = process.env['GITHUB_PATH'] || '';\n    if (filePath) {\n        file_command_1.issueCommand('PATH', inputPath);\n    }\n    else {\n        command_1.issueCommand('add-path', {}, inputPath);\n    }\n    process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;\n}\nexports.addPath = addPath;\n/**\n * Gets the value of an input.\n * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed.\n * Returns an empty string if the value is not defined.\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   string\n */\nfunction getInput(name, options) {\n    const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';\n    if (options && options.required && !val) {\n        throw new Error(`Input required and not supplied: ${name}`);\n    }\n    if (options && options.trimWhitespace === false) {\n        return val;\n    }\n    return val.trim();\n}\nexports.getInput = getInput;\n/**\n * Gets the values of an multiline input.  Each value is also trimmed.\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   string[]\n *\n */\nfunction getMultilineInput(name, options) {\n    const inputs = getInput(name, options)\n        .split('\\n')\n        .filter(x => x !== '');\n    return inputs;\n}\nexports.getMultilineInput = getMultilineInput;\n/**\n * Gets the input value of the boolean type in the YAML 1.2 \"core schema\" specification.\n * Support boolean input list: `true | True | TRUE | false | False | FALSE` .\n * The return value is also in boolean type.\n * ref: https://yaml.org/spec/1.2/spec.html#id2804923\n *\n * @param     name     name of the input to get\n * @param     options  optional. See InputOptions.\n * @returns   boolean\n */\nfunction getBooleanInput(name, options) {\n    const trueValue = ['true', 'True', 'TRUE'];\n    const falseValue = ['false', 'False', 'FALSE'];\n    const val = getInput(name, options);\n    if (trueValue.includes(val))\n        return true;\n    if (falseValue.includes(val))\n        return false;\n    throw new TypeError(`Input does not meet YAML 1.2 \"Core Schema\" specification: ${name}\\n` +\n        `Support boolean input list: \\`true | True | TRUE | false | False | FALSE\\``);\n}\nexports.getBooleanInput = getBooleanInput;\n/**\n * Sets the value of an output.\n *\n * @param     name     name of the output to set\n * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction setOutput(name, value) {\n    process.stdout.write(os.EOL);\n    command_1.issueCommand('set-output', { name }, value);\n}\nexports.setOutput = setOutput;\n/**\n * Enables or disables the echoing of commands into stdout for the rest of the step.\n * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.\n *\n */\nfunction setCommandEcho(enabled) {\n    command_1.issue('echo', enabled ? 'on' : 'off');\n}\nexports.setCommandEcho = setCommandEcho;\n//-----------------------------------------------------------------------\n// Results\n//-----------------------------------------------------------------------\n/**\n * Sets the action status to failed.\n * When the action exits it will be with an exit code of 1\n * @param message add error issue message\n */\nfunction setFailed(message) {\n    process.exitCode = ExitCode.Failure;\n    error(message);\n}\nexports.setFailed = setFailed;\n//-----------------------------------------------------------------------\n// Logging Commands\n//-----------------------------------------------------------------------\n/**\n * Gets whether Actions Step Debug is on or not\n */\nfunction isDebug() {\n    return process.env['RUNNER_DEBUG'] === '1';\n}\nexports.isDebug = isDebug;\n/**\n * Writes debug message to user log\n * @param message debug message\n */\nfunction debug(message) {\n    command_1.issueCommand('debug', {}, message);\n}\nexports.debug = debug;\n/**\n * Adds an error issue\n * @param message error issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction error(message, properties = {}) {\n    command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.error = error;\n/**\n * Adds a warning issue\n * @param message warning issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction warning(message, properties = {}) {\n    command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.warning = warning;\n/**\n * Adds a notice issue\n * @param message notice issue message. Errors will be converted to string via toString()\n * @param properties optional properties to add to the annotation.\n */\nfunction notice(message, properties = {}) {\n    command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message);\n}\nexports.notice = notice;\n/**\n * Writes info to log with console.log.\n * @param message info message\n */\nfunction info(message) {\n    process.stdout.write(message + os.EOL);\n}\nexports.info = info;\n/**\n * Begin an output group.\n *\n * Output until the next `groupEnd` will be foldable in this group\n *\n * @param name The name of the output group\n */\nfunction startGroup(name) {\n    command_1.issue('group', name);\n}\nexports.startGroup = startGroup;\n/**\n * End an output group.\n */\nfunction endGroup() {\n    command_1.issue('endgroup');\n}\nexports.endGroup = endGroup;\n/**\n * Wrap an asynchronous function call in a group.\n *\n * Returns the same type as the function itself.\n *\n * @param name The name of the group\n * @param fn The function to wrap in the group\n */\nfunction group(name, fn) {\n    return __awaiter(this, void 0, void 0, function* () {\n        startGroup(name);\n        let result;\n        try {\n            result = yield fn();\n        }\n        finally {\n            endGroup();\n        }\n        return result;\n    });\n}\nexports.group = group;\n//-----------------------------------------------------------------------\n// Wrapper action state\n//-----------------------------------------------------------------------\n/**\n * Saves state for current action, the state can only be retrieved by this action's post job execution.\n *\n * @param     name     name of the state to store\n * @param     value    value to store. Non-string values will be converted to a string via JSON.stringify\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction saveState(name, value) {\n    command_1.issueCommand('save-state', { name }, value);\n}\nexports.saveState = saveState;\n/**\n * Gets the value of an state set by this action's main execution.\n *\n * @param     name     name of the state to get\n * @returns   string\n */\nfunction getState(name) {\n    return process.env[`STATE_${name}`] || '';\n}\nexports.getState = getState;\nfunction getIDToken(aud) {\n    return __awaiter(this, void 0, void 0, function* () {\n        return yield oidc_utils_1.OidcClient.getIDToken(aud);\n    });\n}\nexports.getIDToken = getIDToken;\n//# sourceMappingURL=core.js.map\n\n/***/ }),\n\n/***/ 717:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// For internal use, subject to change.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.issueCommand = void 0;\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst fs = __importStar(__webpack_require__(5747));\nconst os = __importStar(__webpack_require__(2087));\nconst utils_1 = __webpack_require__(5278);\nfunction issueCommand(command, message) {\n    const filePath = process.env[`GITHUB_${command}`];\n    if (!filePath) {\n        throw new Error(`Unable to find environment variable for file command ${command}`);\n    }\n    if (!fs.existsSync(filePath)) {\n        throw new Error(`Missing file at path: ${filePath}`);\n    }\n    fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {\n        encoding: 'utf8'\n    });\n}\nexports.issueCommand = issueCommand;\n//# sourceMappingURL=file-command.js.map\n\n/***/ }),\n\n/***/ 8041:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.OidcClient = void 0;\nconst http_client_1 = __webpack_require__(9925);\nconst auth_1 = __webpack_require__(3702);\nconst core_1 = __webpack_require__(2186);\nclass OidcClient {\n    static createHttpClient(allowRetry = true, maxRetry = 10) {\n        const requestOptions = {\n            allowRetries: allowRetry,\n            maxRetries: maxRetry\n        };\n        return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions);\n    }\n    static getRequestToken() {\n        const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'];\n        if (!token) {\n            throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable');\n        }\n        return token;\n    }\n    static getIDTokenUrl() {\n        const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL'];\n        if (!runtimeUrl) {\n            throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable');\n        }\n        return runtimeUrl;\n    }\n    static getCall(id_token_url) {\n        var _a;\n        return __awaiter(this, void 0, void 0, function* () {\n            const httpclient = OidcClient.createHttpClient();\n            const res = yield httpclient\n                .getJson(id_token_url)\n                .catch(error => {\n                throw new Error(`Failed to get ID Token. \\n \n        Error Code : ${error.statusCode}\\n \n        Error Message: ${error.result.message}`);\n            });\n            const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value;\n            if (!id_token) {\n                throw new Error('Response json body do not have ID Token field');\n            }\n            return id_token;\n        });\n    }\n    static getIDToken(audience) {\n        return __awaiter(this, void 0, void 0, function* () {\n            try {\n                // New ID Token is requested from action service\n                let id_token_url = OidcClient.getIDTokenUrl();\n                if (audience) {\n                    const encodedAudience = encodeURIComponent(audience);\n                    id_token_url = `${id_token_url}&audience=${encodedAudience}`;\n                }\n                core_1.debug(`ID token url is ${id_token_url}`);\n                const id_token = yield OidcClient.getCall(id_token_url);\n                core_1.setSecret(id_token);\n                return id_token;\n            }\n            catch (error) {\n                throw new Error(`Error message: ${error.message}`);\n            }\n        });\n    }\n}\nexports.OidcClient = OidcClient;\n//# sourceMappingURL=oidc-utils.js.map\n\n/***/ }),\n\n/***/ 5278:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n// We use any as a valid input type\n/* eslint-disable @typescript-eslint/no-explicit-any */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.toCommandProperties = exports.toCommandValue = void 0;\n/**\n * Sanitizes an input into a string so it can be passed into issueCommand safely\n * @param input input to sanitize into a string\n */\nfunction toCommandValue(input) {\n    if (input === null || input === undefined) {\n        return '';\n    }\n    else if (typeof input === 'string' || input instanceof String) {\n        return input;\n    }\n    return JSON.stringify(input);\n}\nexports.toCommandValue = toCommandValue;\n/**\n *\n * @param annotationProperties\n * @returns The command properties to send with the actual annotation command\n * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646\n */\nfunction toCommandProperties(annotationProperties) {\n    if (!Object.keys(annotationProperties).length) {\n        return {};\n    }\n    return {\n        title: annotationProperties.title,\n        file: annotationProperties.file,\n        line: annotationProperties.startLine,\n        endLine: annotationProperties.endLine,\n        col: annotationProperties.startColumn,\n        endColumn: annotationProperties.endColumn\n    };\n}\nexports.toCommandProperties = toCommandProperties;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 4087:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Context = void 0;\nconst fs_1 = __webpack_require__(5747);\nconst os_1 = __webpack_require__(2087);\nclass Context {\n    /**\n     * Hydrate the context from the environment\n     */\n    constructor() {\n        this.payload = {};\n        if (process.env.GITHUB_EVENT_PATH) {\n            if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) {\n                this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' }));\n            }\n            else {\n                const path = process.env.GITHUB_EVENT_PATH;\n                process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`);\n            }\n        }\n        this.eventName = process.env.GITHUB_EVENT_NAME;\n        this.sha = process.env.GITHUB_SHA;\n        this.ref = process.env.GITHUB_REF;\n        this.workflow = process.env.GITHUB_WORKFLOW;\n        this.action = process.env.GITHUB_ACTION;\n        this.actor = process.env.GITHUB_ACTOR;\n        this.job = process.env.GITHUB_JOB;\n        this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10);\n        this.runId = parseInt(process.env.GITHUB_RUN_ID, 10);\n    }\n    get issue() {\n        const payload = this.payload;\n        return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number });\n    }\n    get repo() {\n        if (process.env.GITHUB_REPOSITORY) {\n            const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');\n            return { owner, repo };\n        }\n        if (this.payload.repository) {\n            return {\n                owner: this.payload.repository.owner.login,\n                repo: this.payload.repository.name\n            };\n        }\n        throw new Error(\"context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'\");\n    }\n}\nexports.Context = Context;\n//# sourceMappingURL=context.js.map\n\n/***/ }),\n\n/***/ 5438:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getOctokit = exports.context = void 0;\nconst Context = __importStar(__webpack_require__(4087));\nconst utils_1 = __webpack_require__(3030);\nexports.context = new Context.Context();\n/**\n * Returns a hydrated octokit ready to use for GitHub Actions\n *\n * @param     token    the repo PAT or GITHUB_TOKEN\n * @param     options  other options to set\n */\nfunction getOctokit(token, options) {\n    return new utils_1.GitHub(utils_1.getOctokitOptions(token, options));\n}\nexports.getOctokit = getOctokit;\n//# sourceMappingURL=github.js.map\n\n/***/ }),\n\n/***/ 7914:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0;\nconst httpClient = __importStar(__webpack_require__(9925));\nfunction getAuthString(token, options) {\n    if (!token && !options.auth) {\n        throw new Error('Parameter token or opts.auth is required');\n    }\n    else if (token && options.auth) {\n        throw new Error('Parameters token and opts.auth may not both be specified');\n    }\n    return typeof options.auth === 'string' ? options.auth : `token ${token}`;\n}\nexports.getAuthString = getAuthString;\nfunction getProxyAgent(destinationUrl) {\n    const hc = new httpClient.HttpClient();\n    return hc.getAgent(destinationUrl);\n}\nexports.getProxyAgent = getProxyAgent;\nfunction getApiBaseUrl() {\n    return process.env['GITHUB_API_URL'] || 'https://api.github.com';\n}\nexports.getApiBaseUrl = getApiBaseUrl;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 3030:\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getOctokitOptions = exports.GitHub = exports.context = void 0;\nconst Context = __importStar(__webpack_require__(4087));\nconst Utils = __importStar(__webpack_require__(7914));\n// octokit + plugins\nconst core_1 = __webpack_require__(6762);\nconst plugin_rest_endpoint_methods_1 = __webpack_require__(3044);\nconst plugin_paginate_rest_1 = __webpack_require__(4193);\nexports.context = new Context.Context();\nconst baseUrl = Utils.getApiBaseUrl();\nconst defaults = {\n    baseUrl,\n    request: {\n        agent: Utils.getProxyAgent(baseUrl)\n    }\n};\nexports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(defaults);\n/**\n * Convience function to correctly format Octokit Options to pass into the constructor.\n *\n * @param     token    the repo PAT or GITHUB_TOKEN\n * @param     options  other options to set\n */\nfunction getOctokitOptions(token, options) {\n    const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller\n    // Auth\n    const auth = Utils.getAuthString(token, opts);\n    if (auth) {\n        opts.auth = auth;\n    }\n    return opts;\n}\nexports.getOctokitOptions = getOctokitOptions;\n//# sourceMappingURL=utils.js.map\n\n/***/ }),\n\n/***/ 3702:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nclass BasicCredentialHandler {\n    constructor(username, password) {\n        this.username = username;\n        this.password = password;\n    }\n    prepareRequest(options) {\n        options.headers['Authorization'] =\n            'Basic ' +\n                Buffer.from(this.username + ':' + this.password).toString('base64');\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication(response) {\n        return false;\n    }\n    handleAuthentication(httpClient, requestInfo, objs) {\n        return null;\n    }\n}\nexports.BasicCredentialHandler = BasicCredentialHandler;\nclass BearerCredentialHandler {\n    constructor(token) {\n        this.token = token;\n    }\n    // currently implements pre-authorization\n    // TODO: support preAuth = false where it hooks on 401\n    prepareRequest(options) {\n        options.headers['Authorization'] = 'Bearer ' + this.token;\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication(response) {\n        return false;\n    }\n    handleAuthentication(httpClient, requestInfo, objs) {\n        return null;\n    }\n}\nexports.BearerCredentialHandler = BearerCredentialHandler;\nclass PersonalAccessTokenCredentialHandler {\n    constructor(token) {\n        this.token = token;\n    }\n    // currently implements pre-authorization\n    // TODO: support preAuth = false where it hooks on 401\n    prepareRequest(options) {\n        options.headers['Authorization'] =\n            'Basic ' + Buffer.from('PAT:' + this.token).toString('base64');\n    }\n    // This handler cannot handle 401\n    canHandleAuthentication(response) {\n        return false;\n    }\n    handleAuthentication(httpClient, requestInfo, objs) {\n        return null;\n    }\n}\nexports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler;\n\n\n/***/ }),\n\n/***/ 9925:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst http = __webpack_require__(8605);\nconst https = __webpack_require__(7211);\nconst pm = __webpack_require__(6443);\nlet tunnel;\nvar HttpCodes;\n(function (HttpCodes) {\n    HttpCodes[HttpCodes[\"OK\"] = 200] = \"OK\";\n    HttpCodes[HttpCodes[\"MultipleChoices\"] = 300] = \"MultipleChoices\";\n    HttpCodes[HttpCodes[\"MovedPermanently\"] = 301] = \"MovedPermanently\";\n    HttpCodes[HttpCodes[\"ResourceMoved\"] = 302] = \"ResourceMoved\";\n    HttpCodes[HttpCodes[\"SeeOther\"] = 303] = \"SeeOther\";\n    HttpCodes[HttpCodes[\"NotModified\"] = 304] = \"NotModified\";\n    HttpCodes[HttpCodes[\"UseProxy\"] = 305] = \"UseProxy\";\n    HttpCodes[HttpCodes[\"SwitchProxy\"] = 306] = \"SwitchProxy\";\n    HttpCodes[HttpCodes[\"TemporaryRedirect\"] = 307] = \"TemporaryRedirect\";\n    HttpCodes[HttpCodes[\"PermanentRedirect\"] = 308] = \"PermanentRedirect\";\n    HttpCodes[HttpCodes[\"BadRequest\"] = 400] = \"BadRequest\";\n    HttpCodes[HttpCodes[\"Unauthorized\"] = 401] = \"Unauthorized\";\n    HttpCodes[HttpCodes[\"PaymentRequired\"] = 402] = \"PaymentRequired\";\n    HttpCodes[HttpCodes[\"Forbidden\"] = 403] = \"Forbidden\";\n    HttpCodes[HttpCodes[\"NotFound\"] = 404] = \"NotFound\";\n    HttpCodes[HttpCodes[\"MethodNotAllowed\"] = 405] = \"MethodNotAllowed\";\n    HttpCodes[HttpCodes[\"NotAcceptable\"] = 406] = \"NotAcceptable\";\n    HttpCodes[HttpCodes[\"ProxyAuthenticationRequired\"] = 407] = \"ProxyAuthenticationRequired\";\n    HttpCodes[HttpCodes[\"RequestTimeout\"] = 408] = \"RequestTimeout\";\n    HttpCodes[HttpCodes[\"Conflict\"] = 409] = \"Conflict\";\n    HttpCodes[HttpCodes[\"Gone\"] = 410] = \"Gone\";\n    HttpCodes[HttpCodes[\"TooManyRequests\"] = 429] = \"TooManyRequests\";\n    HttpCodes[HttpCodes[\"InternalServerError\"] = 500] = \"InternalServerError\";\n    HttpCodes[HttpCodes[\"NotImplemented\"] = 501] = \"NotImplemented\";\n    HttpCodes[HttpCodes[\"BadGateway\"] = 502] = \"BadGateway\";\n    HttpCodes[HttpCodes[\"ServiceUnavailable\"] = 503] = \"ServiceUnavailable\";\n    HttpCodes[HttpCodes[\"GatewayTimeout\"] = 504] = \"GatewayTimeout\";\n})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));\nvar Headers;\n(function (Headers) {\n    Headers[\"Accept\"] = \"accept\";\n    Headers[\"ContentType\"] = \"content-type\";\n})(Headers = exports.Headers || (exports.Headers = {}));\nvar MediaTypes;\n(function (MediaTypes) {\n    MediaTypes[\"ApplicationJson\"] = \"application/json\";\n})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {}));\n/**\n * Returns the proxy URL, depending upon the supplied url and proxy environment variables.\n * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com\n */\nfunction getProxyUrl(serverUrl) {\n    let proxyUrl = pm.getProxyUrl(new URL(serverUrl));\n    return proxyUrl ? proxyUrl.href : '';\n}\nexports.getProxyUrl = getProxyUrl;\nconst HttpRedirectCodes = [\n    HttpCodes.MovedPermanently,\n    HttpCodes.ResourceMoved,\n    HttpCodes.SeeOther,\n    HttpCodes.TemporaryRedirect,\n    HttpCodes.PermanentRedirect\n];\nconst HttpResponseRetryCodes = [\n    HttpCodes.BadGateway,\n    HttpCodes.ServiceUnavailable,\n    HttpCodes.GatewayTimeout\n];\nconst RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];\nconst ExponentialBackoffCeiling = 10;\nconst ExponentialBackoffTimeSlice = 5;\nclass HttpClientError extends Error {\n    constructor(message, statusCode) {\n        super(message);\n        this.name = 'HttpClientError';\n        this.statusCode = statusCode;\n        Object.setPrototypeOf(this, HttpClientError.prototype);\n    }\n}\nexports.HttpClientError = HttpClientError;\nclass HttpClientResponse {\n    constructor(message) {\n        this.message = message;\n    }\n    readBody() {\n        return new Promise(async (resolve, reject) => {\n            let output = Buffer.alloc(0);\n            this.message.on('data', (chunk) => {\n                output = Buffer.concat([output, chunk]);\n            });\n            this.message.on('end', () => {\n                resolve(output.toString());\n            });\n        });\n    }\n}\nexports.HttpClientResponse = HttpClientResponse;\nfunction isHttps(requestUrl) {\n    let parsedUrl = new URL(requestUrl);\n    return parsedUrl.protocol === 'https:';\n}\nexports.isHttps = isHttps;\nclass HttpClient {\n    constructor(userAgent, handlers, requestOptions) {\n        this._ignoreSslError = false;\n        this._allowRedirects = true;\n        this._allowRedirectDowngrade = false;\n        this._maxRedirects = 50;\n        this._allowRetries = false;\n        this._maxRetries = 1;\n        this._keepAlive = false;\n        this._disposed = false;\n        this.userAgent = userAgent;\n        this.handlers = handlers || [];\n        this.requestOptions = requestOptions;\n        if (requestOptions) {\n            if (requestOptions.ignoreSslError != null) {\n                this._ignoreSslError = requestOptions.ignoreSslError;\n            }\n            this._socketTimeout = requestOptions.socketTimeout;\n            if (requestOptions.allowRedirects != null) {\n                this._allowRedirects = requestOptions.allowRedirects;\n            }\n            if (requestOptions.allowRedirectDowngrade != null) {\n                this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade;\n            }\n            if (requestOptions.maxRedirects != null) {\n                this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);\n            }\n            if (requestOptions.keepAlive != null) {\n                this._keepAlive = requestOptions.keepAlive;\n            }\n            if (requestOptions.allowRetries != null) {\n                this._allowRetries = requestOptions.allowRetries;\n            }\n            if (requestOptions.maxRetries != null) {\n                this._maxRetries = requestOptions.maxRetries;\n            }\n        }\n    }\n    options(requestUrl, additionalHeaders) {\n        return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});\n    }\n    get(requestUrl, additionalHeaders) {\n        return this.request('GET', requestUrl, null, additionalHeaders || {});\n    }\n    del(requestUrl, additionalHeaders) {\n        return this.request('DELETE', requestUrl, null, additionalHeaders || {});\n    }\n    post(requestUrl, data, additionalHeaders) {\n        return this.request('POST', requestUrl, data, additionalHeaders || {});\n    }\n    patch(requestUrl, data, additionalHeaders) {\n        return this.request('PATCH', requestUrl, data, additionalHeaders || {});\n    }\n    put(requestUrl, data, additionalHeaders) {\n        return this.request('PUT', requestUrl, data, additionalHeaders || {});\n    }\n    head(requestUrl, additionalHeaders) {\n        return this.request('HEAD', requestUrl, null, additionalHeaders || {});\n    }\n    sendStream(verb, requestUrl, stream, additionalHeaders) {\n        return this.request(verb, requestUrl, stream, additionalHeaders);\n    }\n    /**\n     * Gets a typed object from an endpoint\n     * Be aware that not found returns a null.  Other errors (4xx, 5xx) reject the promise\n     */\n    async getJson(requestUrl, additionalHeaders = {}) {\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        let res = await this.get(requestUrl, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async postJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.post(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async putJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.put(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    async patchJson(requestUrl, obj, additionalHeaders = {}) {\n        let data = JSON.stringify(obj, null, 2);\n        additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);\n        additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);\n        let res = await this.patch(requestUrl, data, additionalHeaders);\n        return this._processResponse(res, this.requestOptions);\n    }\n    /**\n     * Makes a raw http request.\n     * All other methods such as get, post, patch, and request ultimately call this.\n     * Prefer get, del, post and patch\n     */\n    async request(verb, requestUrl, data, headers) {\n        if (this._disposed) {\n            throw new Error('Client has already been disposed.');\n        }\n        let parsedUrl = new URL(requestUrl);\n        let info = this._prepareRequest(verb, parsedUrl, headers);\n        // Only perform retries on reads since writes may not be idempotent.\n        let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1\n            ? this._maxRetries + 1\n            : 1;\n        let numTries = 0;\n        let response;\n        while (numTries < maxTries) {\n            response = await this.requestRaw(info, data);\n            // Check if it's an authentication challenge\n            if (response &&\n                response.message &&\n                response.message.statusCode === HttpCodes.Unauthorized) {\n                let authenticationHandler;\n                for (let i = 0; i < this.handlers.length; i++) {\n                    if (this.handlers[i].canHandleAuthentication(response)) {\n                        authenticationHandler = this.handlers[i];\n                        break;\n                    }\n                }\n                if (authenticationHandler) {\n                    return authenticationHandler.handleAuthentication(this, info, data);\n                }\n                else {\n                    // We have received an unauthorized response but have no handlers to handle it.\n                    // Let the response return to the caller.\n                    return response;\n                }\n            }\n            let redirectsRemaining = this._maxRedirects;\n            while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 &&\n                this._allowRedirects &&\n                redirectsRemaining > 0) {\n                const redirectUrl = response.message.headers['location'];\n                if (!redirectUrl) {\n                    // if there's no location to redirect to, we won't\n                    break;\n                }\n                let parsedRedirectUrl = new URL(redirectUrl);\n                if (parsedUrl.protocol == 'https:' &&\n                    parsedUrl.protocol != parsedRedirectUrl.protocol &&\n                    !this._allowRedirectDowngrade) {\n                    throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');\n                }\n                // we need to finish reading the response before reassigning response\n                // which will leak the open socket.\n                await response.readBody();\n                // strip authorization header if redirected to a different hostname\n                if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {\n                    for (let header in headers) {\n                        // header names are case insensitive\n                        if (header.toLowerCase() === 'authorization') {\n                            delete headers[header];\n                        }\n                    }\n                }\n                // let's make the request with the new redirectUrl\n                info = this._prepareRequest(verb, parsedRedirectUrl, headers);\n                response = await this.requestRaw(info, data);\n                redirectsRemaining--;\n            }\n            if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) {\n                // If not a retry code, return immediately instead of retrying\n                return response;\n            }\n            numTries += 1;\n            if (numTries < maxTries) {\n                await response.readBody();\n                await this._performExponentialBackoff(numTries);\n            }\n        }\n        return response;\n    }\n    /**\n     * Needs to be called if keepAlive is set to true in request options.\n     */\n    dispose() {\n        if (this._agent) {\n            this._agent.destroy();\n        }\n        this._disposed = true;\n    }\n    /**\n     * Raw request.\n     * @param info\n     * @param data\n     */\n    requestRaw(info, data) {\n        return new Promise((resolve, reject) => {\n            let callbackForResult = function (err, res) {\n                if (err) {\n                    reject(err);\n                }\n                resolve(res);\n            };\n            this.requestRawWithCallback(info, data, callbackForResult);\n        });\n    }\n    /**\n     * Raw request with callback.\n     * @param info\n     * @param data\n     * @param onResult\n     */\n    requestRawWithCallback(info, data, onResult) {\n        let socket;\n        if (typeof data === 'string') {\n            info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');\n        }\n        let callbackCalled = false;\n        let handleResult = (err, res) => {\n            if (!callbackCalled) {\n                callbackCalled = true;\n                onResult(err, res);\n            }\n        };\n        let req = info.httpModule.request(info.options, (msg) => {\n            let res = new HttpClientResponse(msg);\n            handleResult(null, res);\n        });\n        req.on('socket', sock => {\n            socket = sock;\n        });\n        // If we ever get disconnected, we want the socket to timeout eventually\n        req.setTimeout(this._socketTimeout || 3 * 60000, () => {\n            if (socket) {\n                socket.end();\n            }\n            handleResult(new Error('Request timeout: ' + info.options.path), null);\n        });\n        req.on('error', function (err) {\n            // err has statusCode property\n            // res should have headers\n            handleResult(err, null);\n        });\n        if (data && typeof data === 'string') {\n            req.write(data, 'utf8');\n        }\n        if (data && typeof data !== 'string') {\n            data.on('close', function () {\n                req.end();\n            });\n            data.pipe(req);\n        }\n        else {\n            req.end();\n        }\n    }\n    /**\n     * Gets an http agent. This function is useful when you need an http agent that handles\n     * routing through a proxy server - depending upon the url and proxy environment variables.\n     * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com\n     */\n    getAgent(serverUrl) {\n        let parsedUrl = new URL(serverUrl);\n        return this._getAgent(parsedUrl);\n    }\n    _prepareRequest(method, requestUrl, headers) {\n        const info = {};\n        info.parsedUrl = requestUrl;\n        const usingSsl = info.parsedUrl.protocol === 'https:';\n        info.httpModule = usingSsl ? https : http;\n        const defaultPort = usingSsl ? 443 : 80;\n        info.options = {};\n        info.options.host = info.parsedUrl.hostname;\n        info.options.port = info.parsedUrl.port\n            ? parseInt(info.parsedUrl.port)\n            : defaultPort;\n        info.options.path =\n            (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');\n        info.options.method = method;\n        info.options.headers = this._mergeHeaders(headers);\n        if (this.userAgent != null) {\n            info.options.headers['user-agent'] = this.userAgent;\n        }\n        info.options.agent = this._getAgent(info.parsedUrl);\n        // gives handlers an opportunity to participate\n        if (this.handlers) {\n            this.handlers.forEach(handler => {\n                handler.prepareRequest(info.options);\n            });\n        }\n        return info;\n    }\n    _mergeHeaders(headers) {\n        const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});\n        if (this.requestOptions && this.requestOptions.headers) {\n            return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));\n        }\n        return lowercaseKeys(headers || {});\n    }\n    _getExistingOrDefaultHeader(additionalHeaders, header, _default) {\n        const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});\n        let clientHeader;\n        if (this.requestOptions && this.requestOptions.headers) {\n            clientHeader = lowercaseKeys(this.requestOptions.headers)[header];\n        }\n        return additionalHeaders[header] || clientHeader || _default;\n    }\n    _getAgent(parsedUrl) {\n        let agent;\n        let proxyUrl = pm.getProxyUrl(parsedUrl);\n        let useProxy = proxyUrl && proxyUrl.hostname;\n        if (this._keepAlive && useProxy) {\n            agent = this._proxyAgent;\n        }\n        if (this._keepAlive && !useProxy) {\n            agent = this._agent;\n        }\n        // if agent is already assigned use that agent.\n        if (!!agent) {\n            return agent;\n        }\n        const usingSsl = parsedUrl.protocol === 'https:';\n        let maxSockets = 100;\n        if (!!this.requestOptions) {\n            maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;\n        }\n        if (useProxy) {\n            // If using proxy, need tunnel\n            if (!tunnel) {\n                tunnel = __webpack_require__(4294);\n            }\n            const agentOptions = {\n                maxSockets: maxSockets,\n                keepAlive: this._keepAlive,\n                proxy: {\n                    ...((proxyUrl.username || proxyUrl.password) && {\n                        proxyAuth: `${proxyUrl.username}:${proxyUrl.password}`\n                    }),\n                    host: proxyUrl.hostname,\n                    port: proxyUrl.port\n                }\n            };\n            let tunnelAgent;\n            const overHttps = proxyUrl.protocol === 'https:';\n            if (usingSsl) {\n                tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;\n            }\n            else {\n                tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;\n            }\n            agent = tunnelAgent(agentOptions);\n            this._proxyAgent = agent;\n        }\n        // if reusing agent across request and tunneling agent isn't assigned create a new agent\n        if (this._keepAlive && !agent) {\n            const options = { keepAlive: this._keepAlive, maxSockets: maxSockets };\n            agent = usingSsl ? new https.Agent(options) : new http.Agent(options);\n            this._agent = agent;\n        }\n        // if not using private agent and tunnel agent isn't setup then use global agent\n        if (!agent) {\n            agent = usingSsl ? https.globalAgent : http.globalAgent;\n        }\n        if (usingSsl && this._ignoreSslError) {\n            // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process\n            // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options\n            // we have to cast it to any and change it directly\n            agent.options = Object.assign(agent.options || {}, {\n                rejectUnauthorized: false\n            });\n        }\n        return agent;\n    }\n    _performExponentialBackoff(retryNumber) {\n        retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);\n        const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);\n        return new Promise(resolve => setTimeout(() => resolve(), ms));\n    }\n    static dateTimeDeserializer(key, value) {\n        if (typeof value === 'string') {\n            let a = new Date(value);\n            if (!isNaN(a.valueOf())) {\n                return a;\n            }\n        }\n        return value;\n    }\n    async _processResponse(res, options) {\n        return new Promise(async (resolve, reject) => {\n            const statusCode = res.message.statusCode;\n            const response = {\n                statusCode: statusCode,\n                result: null,\n                headers: {}\n            };\n            // not found leads to null obj returned\n            if (statusCode == HttpCodes.NotFound) {\n                resolve(response);\n            }\n            let obj;\n            let contents;\n            // get the result from the body\n            try {\n                contents = await res.readBody();\n                if (contents && contents.length > 0) {\n                    if (options && options.deserializeDates) {\n                        obj = JSON.parse(contents, HttpClient.dateTimeDeserializer);\n                    }\n                    else {\n                        obj = JSON.parse(contents);\n                    }\n                    response.result = obj;\n                }\n                response.headers = res.message.headers;\n            }\n            catch (err) {\n                // Invalid resource (contents not json);  leaving result obj null\n            }\n            // note that 3xx redirects are handled by the http layer.\n            if (statusCode > 299) {\n                let msg;\n                // if exception/error in body, attempt to get better error\n                if (obj && obj.message) {\n                    msg = obj.message;\n                }\n                else if (contents && contents.length > 0) {\n                    // it may be the case that the exception is in the body message as string\n                    msg = contents;\n                }\n                else {\n                    msg = 'Failed request: (' + statusCode + ')';\n                }\n                let err = new HttpClientError(msg, statusCode);\n                err.result = response.result;\n                reject(err);\n            }\n            else {\n                resolve(response);\n            }\n        });\n    }\n}\nexports.HttpClient = HttpClient;\n\n\n/***/ }),\n\n/***/ 6443:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nfunction getProxyUrl(reqUrl) {\n    let usingSsl = reqUrl.protocol === 'https:';\n    let proxyUrl;\n    if (checkBypass(reqUrl)) {\n        return proxyUrl;\n    }\n    let proxyVar;\n    if (usingSsl) {\n        proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY'];\n    }\n    else {\n        proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY'];\n    }\n    if (proxyVar) {\n        proxyUrl = new URL(proxyVar);\n    }\n    return proxyUrl;\n}\nexports.getProxyUrl = getProxyUrl;\nfunction checkBypass(reqUrl) {\n    if (!reqUrl.hostname) {\n        return false;\n    }\n    let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';\n    if (!noProxy) {\n        return false;\n    }\n    // Determine the request port\n    let reqPort;\n    if (reqUrl.port) {\n        reqPort = Number(reqUrl.port);\n    }\n    else if (reqUrl.protocol === 'http:') {\n        reqPort = 80;\n    }\n    else if (reqUrl.protocol === 'https:') {\n        reqPort = 443;\n    }\n    // Format the request hostname and hostname with port\n    let upperReqHosts = [reqUrl.hostname.toUpperCase()];\n    if (typeof reqPort === 'number') {\n        upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);\n    }\n    // Compare request host against noproxy\n    for (let upperNoProxyItem of noProxy\n        .split(',')\n        .map(x => x.trim().toUpperCase())\n        .filter(x => x)) {\n        if (upperReqHosts.some(x => x === upperNoProxyItem)) {\n            return true;\n        }\n    }\n    return false;\n}\nexports.checkBypass = checkBypass;\n\n\n/***/ }),\n\n/***/ 334:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nconst REGEX_IS_INSTALLATION_LEGACY = /^v1\\./;\nconst REGEX_IS_INSTALLATION = /^ghs_/;\nconst REGEX_IS_USER_TO_SERVER = /^ghu_/;\nasync function auth(token) {\n  const isApp = token.split(/\\./).length === 3;\n  const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token);\n  const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token);\n  const tokenType = isApp ? \"app\" : isInstallation ? \"installation\" : isUserToServer ? \"user-to-server\" : \"oauth\";\n  return {\n    type: \"token\",\n    token: token,\n    tokenType\n  };\n}\n\n/**\n * Prefix token for usage in the Authorization header\n *\n * @param token OAuth token or JSON Web Token\n */\nfunction withAuthorizationPrefix(token) {\n  if (token.split(/\\./).length === 3) {\n    return `bearer ${token}`;\n  }\n\n  return `token ${token}`;\n}\n\nasync function hook(token, request, route, parameters) {\n  const endpoint = request.endpoint.merge(route, parameters);\n  endpoint.headers.authorization = withAuthorizationPrefix(token);\n  return request(endpoint);\n}\n\nconst createTokenAuth = function createTokenAuth(token) {\n  if (!token) {\n    throw new Error(\"[@octokit/auth-token] No token passed to createTokenAuth\");\n  }\n\n  if (typeof token !== \"string\") {\n    throw new Error(\"[@octokit/auth-token] Token passed to createTokenAuth is not a string\");\n  }\n\n  token = token.replace(/^(token|bearer) +/i, \"\");\n  return Object.assign(auth.bind(null, token), {\n    hook: hook.bind(null, token)\n  });\n};\n\nexports.createTokenAuth = createTokenAuth;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 6762:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar universalUserAgent = __webpack_require__(5030);\nvar beforeAfterHook = __webpack_require__(3682);\nvar request = __webpack_require__(6234);\nvar graphql = __webpack_require__(8467);\nvar authToken = __webpack_require__(334);\n\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n  if (source == null) return {};\n  var target = {};\n  var sourceKeys = Object.keys(source);\n  var key, i;\n\n  for (i = 0; i < sourceKeys.length; i++) {\n    key = sourceKeys[i];\n    if (excluded.indexOf(key) >= 0) continue;\n    target[key] = source[key];\n  }\n\n  return target;\n}\n\nfunction _objectWithoutProperties(source, excluded) {\n  if (source == null) return {};\n\n  var target = _objectWithoutPropertiesLoose(source, excluded);\n\n  var key, i;\n\n  if (Object.getOwnPropertySymbols) {\n    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n    for (i = 0; i < sourceSymbolKeys.length; i++) {\n      key = sourceSymbolKeys[i];\n      if (excluded.indexOf(key) >= 0) continue;\n      if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n      target[key] = source[key];\n    }\n  }\n\n  return target;\n}\n\nconst VERSION = \"3.5.1\";\n\nconst _excluded = [\"authStrategy\"];\nclass Octokit {\n  constructor(options = {}) {\n    const hook = new beforeAfterHook.Collection();\n    const requestDefaults = {\n      baseUrl: request.request.endpoint.DEFAULTS.baseUrl,\n      headers: {},\n      request: Object.assign({}, options.request, {\n        // @ts-ignore internal usage only, no need to type\n        hook: hook.bind(null, \"request\")\n      }),\n      mediaType: {\n        previews: [],\n        format: \"\"\n      }\n    }; // prepend default user agent with `options.userAgent` if set\n\n    requestDefaults.headers[\"user-agent\"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(\" \");\n\n    if (options.baseUrl) {\n      requestDefaults.baseUrl = options.baseUrl;\n    }\n\n    if (options.previews) {\n      requestDefaults.mediaType.previews = options.previews;\n    }\n\n    if (options.timeZone) {\n      requestDefaults.headers[\"time-zone\"] = options.timeZone;\n    }\n\n    this.request = request.request.defaults(requestDefaults);\n    this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults);\n    this.log = Object.assign({\n      debug: () => {},\n      info: () => {},\n      warn: console.warn.bind(console),\n      error: console.error.bind(console)\n    }, options.log);\n    this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance\n    //     is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered.\n    // (2) If only `options.auth` is set, use the default token authentication strategy.\n    // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance.\n    // TODO: type `options.auth` based on `options.authStrategy`.\n\n    if (!options.authStrategy) {\n      if (!options.auth) {\n        // (1)\n        this.auth = async () => ({\n          type: \"unauthenticated\"\n        });\n      } else {\n        // (2)\n        const auth = authToken.createTokenAuth(options.auth); // @ts-ignore  ¯\\_(ツ)_/¯\n\n        hook.wrap(\"request\", auth.hook);\n        this.auth = auth;\n      }\n    } else {\n      const {\n        authStrategy\n      } = options,\n            otherOptions = _objectWithoutProperties(options, _excluded);\n\n      const auth = authStrategy(Object.assign({\n        request: this.request,\n        log: this.log,\n        // we pass the current octokit instance as well as its constructor options\n        // to allow for authentication strategies that return a new octokit instance\n        // that shares the same internal state as the current one. The original\n        // requirement for this was the \"event-octokit\" authentication strategy\n        // of https://github.com/probot/octokit-auth-probot.\n        octokit: this,\n        octokitOptions: otherOptions\n      }, options.auth)); // @ts-ignore  ¯\\_(ツ)_/¯\n\n      hook.wrap(\"request\", auth.hook);\n      this.auth = auth;\n    } // apply plugins\n    // https://stackoverflow.com/a/16345172\n\n\n    const classConstructor = this.constructor;\n    classConstructor.plugins.forEach(plugin => {\n      Object.assign(this, plugin(this, options));\n    });\n  }\n\n  static defaults(defaults) {\n    const OctokitWithDefaults = class extends this {\n      constructor(...args) {\n        const options = args[0] || {};\n\n        if (typeof defaults === \"function\") {\n          super(defaults(options));\n          return;\n        }\n\n        super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? {\n          userAgent: `${options.userAgent} ${defaults.userAgent}`\n        } : null));\n      }\n\n    };\n    return OctokitWithDefaults;\n  }\n  /**\n   * Attach a plugin (or many) to your Octokit instance.\n   *\n   * @example\n   * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...)\n   */\n\n\n  static plugin(...newPlugins) {\n    var _a;\n\n    const currentPlugins = this.plugins;\n    const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a);\n    return NewOctokit;\n  }\n\n}\nOctokit.VERSION = VERSION;\nOctokit.plugins = [];\n\nexports.Octokit = Octokit;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 9440:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar isPlainObject = __webpack_require__(3287);\nvar universalUserAgent = __webpack_require__(5030);\n\nfunction lowercaseKeys(object) {\n  if (!object) {\n    return {};\n  }\n\n  return Object.keys(object).reduce((newObj, key) => {\n    newObj[key.toLowerCase()] = object[key];\n    return newObj;\n  }, {});\n}\n\nfunction mergeDeep(defaults, options) {\n  const result = Object.assign({}, defaults);\n  Object.keys(options).forEach(key => {\n    if (isPlainObject.isPlainObject(options[key])) {\n      if (!(key in defaults)) Object.assign(result, {\n        [key]: options[key]\n      });else result[key] = mergeDeep(defaults[key], options[key]);\n    } else {\n      Object.assign(result, {\n        [key]: options[key]\n      });\n    }\n  });\n  return result;\n}\n\nfunction removeUndefinedProperties(obj) {\n  for (const key in obj) {\n    if (obj[key] === undefined) {\n      delete obj[key];\n    }\n  }\n\n  return obj;\n}\n\nfunction merge(defaults, route, options) {\n  if (typeof route === \"string\") {\n    let [method, url] = route.split(\" \");\n    options = Object.assign(url ? {\n      method,\n      url\n    } : {\n      url: method\n    }, options);\n  } else {\n    options = Object.assign({}, route);\n  } // lowercase header names before merging with defaults to avoid duplicates\n\n\n  options.headers = lowercaseKeys(options.headers); // remove properties with undefined values before merging\n\n  removeUndefinedProperties(options);\n  removeUndefinedProperties(options.headers);\n  const mergedOptions = mergeDeep(defaults || {}, options); // mediaType.previews arrays are merged, instead of overwritten\n\n  if (defaults && defaults.mediaType.previews.length) {\n    mergedOptions.mediaType.previews = defaults.mediaType.previews.filter(preview => !mergedOptions.mediaType.previews.includes(preview)).concat(mergedOptions.mediaType.previews);\n  }\n\n  mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, \"\"));\n  return mergedOptions;\n}\n\nfunction addQueryParameters(url, parameters) {\n  const separator = /\\?/.test(url) ? \"&\" : \"?\";\n  const names = Object.keys(parameters);\n\n  if (names.length === 0) {\n    return url;\n  }\n\n  return url + separator + names.map(name => {\n    if (name === \"q\") {\n      return \"q=\" + parameters.q.split(\"+\").map(encodeURIComponent).join(\"+\");\n    }\n\n    return `${name}=${encodeURIComponent(parameters[name])}`;\n  }).join(\"&\");\n}\n\nconst urlVariableRegex = /\\{[^}]+\\}/g;\n\nfunction removeNonChars(variableName) {\n  return variableName.replace(/^\\W+|\\W+$/g, \"\").split(/,/);\n}\n\nfunction extractUrlVariableNames(url) {\n  const matches = url.match(urlVariableRegex);\n\n  if (!matches) {\n    return [];\n  }\n\n  return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []);\n}\n\nfunction omit(object, keysToOmit) {\n  return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => {\n    obj[key] = object[key];\n    return obj;\n  }, {});\n}\n\n// Based on https://github.com/bramstein/url-template, licensed under BSD\n// TODO: create separate package.\n//\n// Copyright (c) 2012-2014, Bram Stein\n// All rights reserved.\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//  1. Redistributions of source code must retain the above copyright\n//     notice, this list of conditions and the following disclaimer.\n//  2. Redistributions in binary form must reproduce the above copyright\n//     notice, this list of conditions and the following disclaimer in the\n//     documentation and/or other materials provided with the distribution.\n//  3. The name of the author may not be used to endorse or promote products\n//     derived from this software without specific prior written permission.\n// THIS SOFTWARE IS PROVIDED BY THE AUTHOR \"AS IS\" AND ANY EXPRESS OR IMPLIED\n// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n// EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n/* istanbul ignore file */\nfunction encodeReserved(str) {\n  return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) {\n    if (!/%[0-9A-Fa-f]/.test(part)) {\n      part = encodeURI(part).replace(/%5B/g, \"[\").replace(/%5D/g, \"]\");\n    }\n\n    return part;\n  }).join(\"\");\n}\n\nfunction encodeUnreserved(str) {\n  return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {\n    return \"%\" + c.charCodeAt(0).toString(16).toUpperCase();\n  });\n}\n\nfunction encodeValue(operator, value, key) {\n  value = operator === \"+\" || operator === \"#\" ? encodeReserved(value) : encodeUnreserved(value);\n\n  if (key) {\n    return encodeUnreserved(key) + \"=\" + value;\n  } else {\n    return value;\n  }\n}\n\nfunction isDefined(value) {\n  return value !== undefined && value !== null;\n}\n\nfunction isKeyOperator(operator) {\n  return operator === \";\" || operator === \"&\" || operator === \"?\";\n}\n\nfunction getValues(context, operator, key, modifier) {\n  var value = context[key],\n      result = [];\n\n  if (isDefined(value) && value !== \"\") {\n    if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n      value = value.toString();\n\n      if (modifier && modifier !== \"*\") {\n        value = value.substring(0, parseInt(modifier, 10));\n      }\n\n      result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : \"\"));\n    } else {\n      if (modifier === \"*\") {\n        if (Array.isArray(value)) {\n          value.filter(isDefined).forEach(function (value) {\n            result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : \"\"));\n          });\n        } else {\n          Object.keys(value).forEach(function (k) {\n            if (isDefined(value[k])) {\n              result.push(encodeValue(operator, value[k], k));\n            }\n          });\n        }\n      } else {\n        const tmp = [];\n\n        if (Array.isArray(value)) {\n          value.filter(isDefined).forEach(function (value) {\n            tmp.push(encodeValue(operator, value));\n          });\n        } else {\n          Object.keys(value).forEach(function (k) {\n            if (isDefined(value[k])) {\n              tmp.push(encodeUnreserved(k));\n              tmp.push(encodeValue(operator, value[k].toString()));\n            }\n          });\n        }\n\n        if (isKeyOperator(operator)) {\n          result.push(encodeUnreserved(key) + \"=\" + tmp.join(\",\"));\n        } else if (tmp.length !== 0) {\n          result.push(tmp.join(\",\"));\n        }\n      }\n    }\n  } else {\n    if (operator === \";\") {\n      if (isDefined(value)) {\n        result.push(encodeUnreserved(key));\n      }\n    } else if (value === \"\" && (operator === \"&\" || operator === \"?\")) {\n      result.push(encodeUnreserved(key) + \"=\");\n    } else if (value === \"\") {\n      result.push(\"\");\n    }\n  }\n\n  return result;\n}\n\nfunction parseUrl(template) {\n  return {\n    expand: expand.bind(null, template)\n  };\n}\n\nfunction expand(template, context) {\n  var operators = [\"+\", \"#\", \".\", \"/\", \";\", \"?\", \"&\"];\n  return template.replace(/\\{([^\\{\\}]+)\\}|([^\\{\\}]+)/g, function (_, expression, literal) {\n    if (expression) {\n      let operator = \"\";\n      const values = [];\n\n      if (operators.indexOf(expression.charAt(0)) !== -1) {\n        operator = expression.charAt(0);\n        expression = expression.substr(1);\n      }\n\n      expression.split(/,/g).forEach(function (variable) {\n        var tmp = /([^:\\*]*)(?::(\\d+)|(\\*))?/.exec(variable);\n        values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3]));\n      });\n\n      if (operator && operator !== \"+\") {\n        var separator = \",\";\n\n        if (operator === \"?\") {\n          separator = \"&\";\n        } else if (operator !== \"#\") {\n          separator = operator;\n        }\n\n        return (values.length !== 0 ? operator : \"\") + values.join(separator);\n      } else {\n        return values.join(\",\");\n      }\n    } else {\n      return encodeReserved(literal);\n    }\n  });\n}\n\nfunction parse(options) {\n  // https://fetch.spec.whatwg.org/#methods\n  let method = options.method.toUpperCase(); // replace :varname with {varname} to make it RFC 6570 compatible\n\n  let url = (options.url || \"/\").replace(/:([a-z]\\w+)/g, \"{$1}\");\n  let headers = Object.assign({}, options.headers);\n  let body;\n  let parameters = omit(options, [\"method\", \"baseUrl\", \"url\", \"headers\", \"request\", \"mediaType\"]); // extract variable names from URL to calculate remaining variables later\n\n  const urlVariableNames = extractUrlVariableNames(url);\n  url = parseUrl(url).expand(parameters);\n\n  if (!/^http/.test(url)) {\n    url = options.baseUrl + url;\n  }\n\n  const omittedParameters = Object.keys(options).filter(option => urlVariableNames.includes(option)).concat(\"baseUrl\");\n  const remainingParameters = omit(parameters, omittedParameters);\n  const isBinaryRequest = /application\\/octet-stream/i.test(headers.accept);\n\n  if (!isBinaryRequest) {\n    if (options.mediaType.format) {\n      // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw\n      headers.accept = headers.accept.split(/,/).map(preview => preview.replace(/application\\/vnd(\\.\\w+)(\\.v3)?(\\.\\w+)?(\\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`)).join(\",\");\n    }\n\n    if (options.mediaType.previews.length) {\n      const previewsFromAcceptHeader = headers.accept.match(/[\\w-]+(?=-preview)/g) || [];\n      headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map(preview => {\n        const format = options.mediaType.format ? `.${options.mediaType.format}` : \"+json\";\n        return `application/vnd.github.${preview}-preview${format}`;\n      }).join(\",\");\n    }\n  } // for GET/HEAD requests, set URL query parameters from remaining parameters\n  // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters\n\n\n  if ([\"GET\", \"HEAD\"].includes(method)) {\n    url = addQueryParameters(url, remainingParameters);\n  } else {\n    if (\"data\" in remainingParameters) {\n      body = remainingParameters.data;\n    } else {\n      if (Object.keys(remainingParameters).length) {\n        body = remainingParameters;\n      } else {\n        headers[\"content-length\"] = 0;\n      }\n    }\n  } // default content-type for JSON if body is set\n\n\n  if (!headers[\"content-type\"] && typeof body !== \"undefined\") {\n    headers[\"content-type\"] = \"application/json; charset=utf-8\";\n  } // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body.\n  // fetch does not allow to set `content-length` header, but we can set body to an empty string\n\n\n  if ([\"PATCH\", \"PUT\"].includes(method) && typeof body === \"undefined\") {\n    body = \"\";\n  } // Only return body/request keys if present\n\n\n  return Object.assign({\n    method,\n    url,\n    headers\n  }, typeof body !== \"undefined\" ? {\n    body\n  } : null, options.request ? {\n    request: options.request\n  } : null);\n}\n\nfunction endpointWithDefaults(defaults, route, options) {\n  return parse(merge(defaults, route, options));\n}\n\nfunction withDefaults(oldDefaults, newDefaults) {\n  const DEFAULTS = merge(oldDefaults, newDefaults);\n  const endpoint = endpointWithDefaults.bind(null, DEFAULTS);\n  return Object.assign(endpoint, {\n    DEFAULTS,\n    defaults: withDefaults.bind(null, DEFAULTS),\n    merge: merge.bind(null, DEFAULTS),\n    parse\n  });\n}\n\nconst VERSION = \"6.0.12\";\n\nconst userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`; // DEFAULTS has all properties set that EndpointOptions has, except url.\n// So we use RequestParameters and add method as additional required property.\n\nconst DEFAULTS = {\n  method: \"GET\",\n  baseUrl: \"https://api.github.com\",\n  headers: {\n    accept: \"application/vnd.github.v3+json\",\n    \"user-agent\": userAgent\n  },\n  mediaType: {\n    format: \"\",\n    previews: []\n  }\n};\n\nconst endpoint = withDefaults(null, DEFAULTS);\n\nexports.endpoint = endpoint;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 8467:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nvar request = __webpack_require__(6234);\nvar universalUserAgent = __webpack_require__(5030);\n\nconst VERSION = \"4.8.0\";\n\nfunction _buildMessageForResponseErrors(data) {\n  return `Request failed due to following response errors:\\n` + data.errors.map(e => ` - ${e.message}`).join(\"\\n\");\n}\n\nclass GraphqlResponseError extends Error {\n  constructor(request, headers, response) {\n    super(_buildMessageForResponseErrors(response));\n    this.request = request;\n    this.headers = headers;\n    this.response = response;\n    this.name = \"GraphqlResponseError\"; // Expose the errors and response data in their shorthand properties.\n\n    this.errors = response.errors;\n    this.data = response.data; // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n  }\n\n}\n\nconst NON_VARIABLE_OPTIONS = [\"method\", \"baseUrl\", \"url\", \"headers\", \"request\", \"query\", \"mediaType\"];\nconst FORBIDDEN_VARIABLE_OPTIONS = [\"query\", \"method\", \"url\"];\nconst GHES_V3_SUFFIX_REGEX = /\\/api\\/v3\\/?$/;\nfunction graphql(request, query, options) {\n  if (options) {\n    if (typeof query === \"string\" && \"query\" in options) {\n      return Promise.reject(new Error(`[@octokit/graphql] \"query\" cannot be used as variable name`));\n    }\n\n    for (const key in options) {\n      if (!FORBIDDEN_VARIABLE_OPTIONS.includes(key)) continue;\n      return Promise.reject(new Error(`[@octokit/graphql] \"${key}\" cannot be used as variable name`));\n    }\n  }\n\n  const parsedOptions = typeof query === \"string\" ? Object.assign({\n    query\n  }, options) : query;\n  const requestOptions = Object.keys(parsedOptions).reduce((result, key) => {\n    if (NON_VARIABLE_OPTIONS.includes(key)) {\n      result[key] = parsedOptions[key];\n      return result;\n    }\n\n    if (!result.variables) {\n      result.variables = {};\n    }\n\n    result.variables[key] = parsedOptions[key];\n    return result;\n  }, {}); // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix\n  // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451\n\n  const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl;\n\n  if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) {\n    requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, \"/api/graphql\");\n  }\n\n  return request(requestOptions).then(response => {\n    if (response.data.errors) {\n      const headers = {};\n\n      for (const key of Object.keys(response.headers)) {\n        headers[key] = response.headers[key];\n      }\n\n      throw new GraphqlResponseError(requestOptions, headers, response.data);\n    }\n\n    return response.data.data;\n  });\n}\n\nfunction withDefaults(request$1, newDefaults) {\n  const newRequest = request$1.defaults(newDefaults);\n\n  const newApi = (query, options) => {\n    return graphql(newRequest, query, options);\n  };\n\n  return Object.assign(newApi, {\n    defaults: withDefaults.bind(null, newRequest),\n    endpoint: request.request.endpoint\n  });\n}\n\nconst graphql$1 = withDefaults(request.request, {\n  headers: {\n    \"user-agent\": `octokit-graphql.js/${VERSION} ${universalUserAgent.getUserAgent()}`\n  },\n  method: \"POST\",\n  url: \"/graphql\"\n});\nfunction withCustomRequest(customRequest) {\n  return withDefaults(customRequest, {\n    method: \"POST\",\n    url: \"/graphql\"\n  });\n}\n\nexports.GraphqlResponseError = GraphqlResponseError;\nexports.graphql = graphql$1;\nexports.withCustomRequest = withCustomRequest;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 4193:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nconst VERSION = \"2.17.0\";\n\nfunction ownKeys(object, enumerableOnly) {\n  var keys = Object.keys(object);\n\n  if (Object.getOwnPropertySymbols) {\n    var symbols = Object.getOwnPropertySymbols(object);\n\n    if (enumerableOnly) {\n      symbols = symbols.filter(function (sym) {\n        return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n      });\n    }\n\n    keys.push.apply(keys, symbols);\n  }\n\n  return keys;\n}\n\nfunction _objectSpread2(target) {\n  for (var i = 1; i < arguments.length; i++) {\n    var source = arguments[i] != null ? arguments[i] : {};\n\n    if (i % 2) {\n      ownKeys(Object(source), true).forEach(function (key) {\n        _defineProperty(target, key, source[key]);\n      });\n    } else if (Object.getOwnPropertyDescriptors) {\n      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n    } else {\n      ownKeys(Object(source)).forEach(function (key) {\n        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n      });\n    }\n  }\n\n  return target;\n}\n\nfunction _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\n/**\n * Some “list” response that can be paginated have a different response structure\n *\n * They have a `total_count` key in the response (search also has `incomplete_results`,\n * /installation/repositories also has `repository_selection`), as well as a key with\n * the list of the items which name varies from endpoint to endpoint.\n *\n * Octokit normalizes these responses so that paginated results are always returned following\n * the same structure. One challenge is that if the list response has only one page, no Link\n * header is provided, so this header alone is not sufficient to check wether a response is\n * paginated or not.\n *\n * We check if a \"total_count\" key is present in the response data, but also make sure that\n * a \"url\" property is not, as the \"Get the combined status for a specific ref\" endpoint would\n * otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref\n */\nfunction normalizePaginatedListResponse(response) {\n  // endpoints can respond with 204 if repository is empty\n  if (!response.data) {\n    return _objectSpread2(_objectSpread2({}, response), {}, {\n      data: []\n    });\n  }\n\n  const responseNeedsNormalization = \"total_count\" in response.data && !(\"url\" in response.data);\n  if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way\n  // to retrieve the same information.\n\n  const incompleteResults = response.data.incomplete_results;\n  const repositorySelection = response.data.repository_selection;\n  const totalCount = response.data.total_count;\n  delete response.data.incomplete_results;\n  delete response.data.repository_selection;\n  delete response.data.total_count;\n  const namespaceKey = Object.keys(response.data)[0];\n  const data = response.data[namespaceKey];\n  response.data = data;\n\n  if (typeof incompleteResults !== \"undefined\") {\n    response.data.incomplete_results = incompleteResults;\n  }\n\n  if (typeof repositorySelection !== \"undefined\") {\n    response.data.repository_selection = repositorySelection;\n  }\n\n  response.data.total_count = totalCount;\n  return response;\n}\n\nfunction iterator(octokit, route, parameters) {\n  const options = typeof route === \"function\" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters);\n  const requestMethod = typeof route === \"function\" ? route : octokit.request;\n  const method = options.method;\n  const headers = options.headers;\n  let url = options.url;\n  return {\n    [Symbol.asyncIterator]: () => ({\n      async next() {\n        if (!url) return {\n          done: true\n        };\n\n        try {\n          const response = await requestMethod({\n            method,\n            url,\n            headers\n          });\n          const normalizedResponse = normalizePaginatedListResponse(response); // `response.headers.link` format:\n          // '<https://api.github.com/users/aseemk/followers?page=2>; rel=\"next\", <https://api.github.com/users/aseemk/followers?page=2>; rel=\"last\"'\n          // sets `url` to undefined if \"next\" URL is not present or `link` header is not set\n\n          url = ((normalizedResponse.headers.link || \"\").match(/<([^>]+)>;\\s*rel=\"next\"/) || [])[1];\n          return {\n            value: normalizedResponse\n          };\n        } catch (error) {\n          if (error.status !== 409) throw error;\n          url = \"\";\n          return {\n            value: {\n              status: 200,\n              headers: {},\n              data: []\n            }\n          };\n        }\n      }\n\n    })\n  };\n}\n\nfunction paginate(octokit, route, parameters, mapFn) {\n  if (typeof parameters === \"function\") {\n    mapFn = parameters;\n    parameters = undefined;\n  }\n\n  return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);\n}\n\nfunction gather(octokit, results, iterator, mapFn) {\n  return iterator.next().then(result => {\n    if (result.done) {\n      return results;\n    }\n\n    let earlyExit = false;\n\n    function done() {\n      earlyExit = true;\n    }\n\n    results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data);\n\n    if (earlyExit) {\n      return results;\n    }\n\n    return gather(octokit, results, iterator, mapFn);\n  });\n}\n\nconst composePaginateRest = Object.assign(paginate, {\n  iterator\n});\n\nconst paginatingEndpoints = [\"GET /app/hook/deliveries\", \"GET /app/installations\", \"GET /applications/grants\", \"GET /authorizations\", \"GET /enterprises/{enterprise}/actions/permissions/organizations\", \"GET /enterprises/{enterprise}/actions/runner-groups\", \"GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/organizations\", \"GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/runners\", \"GET /enterprises/{enterprise}/actions/runners\", \"GET /enterprises/{enterprise}/actions/runners/downloads\", \"GET /events\", \"GET /gists\", \"GET /gists/public\", \"GET /gists/starred\", \"GET /gists/{gist_id}/comments\", \"GET /gists/{gist_id}/commits\", \"GET /gists/{gist_id}/forks\", \"GET /installation/repositories\", \"GET /issues\", \"GET /marketplace_listing/plans\", \"GET /marketplace_listing/plans/{plan_id}/accounts\", \"GET /marketplace_listing/stubbed/plans\", \"GET /marketplace_listing/stubbed/plans/{plan_id}/accounts\", \"GET /networks/{owner}/{repo}/events\", \"GET /notifications\", \"GET /organizations\", \"GET /orgs/{org}/actions/permissions/repositories\", \"GET /orgs/{org}/actions/runner-groups\", \"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories\", \"GET /orgs/{org}/actions/runner-groups/{runner_group_id}/runners\", \"GET /orgs/{org}/actions/runners\", \"GET /orgs/{org}/actions/runners/downloads\", \"GET /orgs/{org}/actions/secrets\", \"GET /orgs/{org}/actions/secrets/{secret_name}/repositories\", \"GET /orgs/{org}/blocks\", \"GET /orgs/{org}/credential-authorizations\", \"GET /orgs/{org}/events\", \"GET /orgs/{org}/failed_invitations\", \"GET /orgs/{org}/hooks\", \"GET /orgs/{org}/hooks/{hook_id}/deliveries\", \"GET /orgs/{org}/installations\", \"GET /orgs/{org}/invitations\", \"GET /orgs/{org}/invitations/{invitation_id}/teams\", \"GET /orgs/{org}/issues\", \"GET /orgs/{org}/members\", \"GET /orgs/{org}/migrations\", \"GET /orgs/{org}/migrations/{migration_id}/repositories\", \"GET /orgs/{org}/outside_collaborators\", \"GET /orgs/{org}/packages\", \"GET /orgs/{org}/projects\", \"GET /orgs/{org}/public_members\", \"GET /orgs/{org}/repos\", \"GET /orgs/{org}/secret-scanning/alerts\", \"GET /orgs/{org}/team-sync/groups\", \"GET /orgs/{org}/teams\", \"GET /orgs/{org}/teams/{team_slug}/discussions\", \"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments\", \"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions\", \"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions\", \"GET /orgs/{org}/teams/{team_slug}/invitations\", \"GET /orgs/{org}/teams/{team_slug}/members\", \"GET /orgs/{org}/teams/{team_slug}/projects\", \"GET /orgs/{org}/teams/{team_slug}/repos\", \"GET /orgs/{org}/teams/{team_slug}/team-sync/group-mappings\", \"GET /orgs/{org}/teams/{team_slug}/teams\", \"GET /projects/columns/{column_id}/cards\", \"GET /projects/{project_id}/collaborators\", \"GET /projects/{project_id}/columns\", \"GET /repos/{owner}/{repo}/actions/artifacts\", \"GET /repos/{owner}/{repo}/actions/runners\", \"GET /repos/{owner}/{repo}/actions/runners/downloads\", \"GET /repos/{owner}/{repo}/actions/runs\", \"GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts\", \"GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs\", \"GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs\", \"GET /repos/{owner}/{repo}/actions/secrets\", \"GET /repos/{owner}/{repo}/actions/workflows\", \"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs\", \"GET /repos/{owner}/{repo}/assignees\", \"GET /repos/{owner}/{repo}/autolinks\", \"GET /repos/{owner}/{repo}/branches\", \"GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations\", \"GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs\", \"GET /repos/{owner}/{repo}/code-scanning/alerts\", \"GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances\", \"GET /repos/{owner}/{repo}/code-scanning/analyses\", \"GET /repos/{owner}/{repo}/collaborators\", \"GET /repos/{owner}/{repo}/comments\", \"GET /repos/{owner}/{repo}/comments/{comment_id}/reactions\", \"GET /repos/{owner}/{repo}/commits\", \"GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head\", \"GET /repos/{owner}/{repo}/commits/{commit_sha}/comments\", \"GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls\", \"GET /repos/{owner}/{repo}/commits/{ref}/check-runs\", \"GET /repos/{owner}/{repo}/commits/{ref}/check-suites\", \"GET /repos/{owner}/{repo}/commits/{ref}/statuses\", \"GET /repos/{owner}/{repo}/contributors\", \"GET /repos/{owner}/{repo}/deployments\", \"GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses\", \"GET /repos/{owner}/{repo}/events\", \"GET /repos/{owner}/{repo}/forks\", \"GET /repos/{owner}/{repo}/git/matching-refs/{ref}\", \"GET /repos/{owner}/{repo}/hooks\", \"GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries\", \"GET /repos/{owner}/{repo}/invitations\", \"GET /repos/{owner}/{repo}/issues\", \"GET /repos/{owner}/{repo}/issues/comments\", \"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions\", \"GET /repos/{owner}/{repo}/issues/events\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/comments\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/events\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/labels\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions\", \"GET /repos/{owner}/{repo}/issues/{issue_number}/timeline\", \"GET /repos/{owner}/{repo}/keys\", \"GET /repos/{owner}/{repo}/labels\", \"GET /repos/{owner}/{repo}/milestones\", \"GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels\", \"GET /repos/{owner}/{repo}/notifications\", \"GET /repos/{owner}/{repo}/pages/builds\", \"GET /repos/{owner}/{repo}/projects\", \"GET /repos/{owner}/{repo}/pulls\", \"GET /repos/{owner}/{repo}/pulls/comments\", \"GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/comments\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/commits\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews\", \"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments\", \"GET /repos/{owner}/{repo}/releases\", \"GET /repos/{owner}/{repo}/releases/{release_id}/assets\", \"GET /repos/{owner}/{repo}/secret-scanning/alerts\", \"GET /repos/{owner}/{repo}/stargazers\", \"GET /repos/{owner}/{repo}/subscribers\", \"GET /repos/{owner}/{repo}/tags\", \"GET /repos/{owner}/{repo}/teams\", \"GET /repositories\", \"GET /repositories/{repository_id}/environments/{environment_name}/secrets\", \"GET /scim/v2/enterprises/{enterprise}/Groups\", \"GET /scim/v2/enterprises/{enterprise}/Users\", \"GET /scim/v2/organizations/{org}/Users\", \"GET /search/code\", \"GET /search/commits\", \"GET /search/issues\", \"GET /search/labels\", \"GET /search/repositories\", \"GET /search/topics\", \"GET /search/users\", \"GET /teams/{team_id}/discussions\", \"GET /teams/{team_id}/discussions/{discussion_number}/comments\", \"GET /teams/{team_id}/discussions/{discussion_number}/comments/{comment_number}/reactions\", \"GET /teams/{team_id}/discussions/{discussion_number}/reactions\", \"GET /teams/{team_id}/invitations\", \"GET /teams/{team_id}/members\", \"GET /teams/{team_id}/projects\", \"GET /teams/{team_id}/repos\", \"GET /teams/{team_id}/team-sync/group-mappings\", \"GET /teams/{team_id}/teams\", \"GET /user/blocks\", \"GET /user/emails\", \"GET /user/followers\", \"GET /user/following\", \"GET /user/gpg_keys\", \"GET /user/installations\", \"GET /user/installations/{installation_id}/repositories\", \"GET /user/issues\", \"GET /user/keys\", \"GET /user/marketplace_purchases\", \"GET /user/marketplace_purchases/stubbed\", \"GET /user/memberships/orgs\", \"GET /user/migrations\", \"GET /user/migrations/{migration_id}/repositories\", \"GET /user/orgs\", \"GET /user/packages\", \"GET /user/public_emails\", \"GET /user/repos\", \"GET /user/repository_invitations\", \"GET /user/starred\", \"GET /user/subscriptions\", \"GET /user/teams\", \"GET /users\", \"GET /users/{username}/events\", \"GET /users/{username}/events/orgs/{org}\", \"GET /users/{username}/events/public\", \"GET /users/{username}/followers\", \"GET /users/{username}/following\", \"GET /users/{username}/gists\", \"GET /users/{username}/gpg_keys\", \"GET /users/{username}/keys\", \"GET /users/{username}/orgs\", \"GET /users/{username}/packages\", \"GET /users/{username}/projects\", \"GET /users/{username}/received_events\", \"GET /users/{username}/received_events/public\", \"GET /users/{username}/repos\", \"GET /users/{username}/starred\", \"GET /users/{username}/subscriptions\"];\n\nfunction isPaginatingEndpoint(arg) {\n  if (typeof arg === \"string\") {\n    return paginatingEndpoints.includes(arg);\n  } else {\n    return false;\n  }\n}\n\n/**\n * @param octokit Octokit instance\n * @param options Options passed to Octokit constructor\n */\n\nfunction paginateRest(octokit) {\n  return {\n    paginate: Object.assign(paginate.bind(null, octokit), {\n      iterator: iterator.bind(null, octokit)\n    })\n  };\n}\npaginateRest.VERSION = VERSION;\n\nexports.composePaginateRest = composePaginateRest;\nexports.isPaginatingEndpoint = isPaginatingEndpoint;\nexports.paginateRest = paginateRest;\nexports.paginatingEndpoints = paginatingEndpoints;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 3044:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\nfunction ownKeys(object, enumerableOnly) {\n  var keys = Object.keys(object);\n\n  if (Object.getOwnPropertySymbols) {\n    var symbols = Object.getOwnPropertySymbols(object);\n    if (enumerableOnly) symbols = symbols.filter(function (sym) {\n      return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n    });\n    keys.push.apply(keys, symbols);\n  }\n\n  return keys;\n}\n\nfunction _objectSpread2(target) {\n  for (var i = 1; i < arguments.length; i++) {\n    var source = arguments[i] != null ? arguments[i] : {};\n\n    if (i % 2) {\n      ownKeys(Object(source), true).forEach(function (key) {\n        _defineProperty(target, key, source[key]);\n      });\n    } else if (Object.getOwnPropertyDescriptors) {\n      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n    } else {\n      ownKeys(Object(source)).forEach(function (key) {\n        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n      });\n    }\n  }\n\n  return target;\n}\n\nconst Endpoints = {\n  actions: {\n    addSelectedRepoToOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}\"],\n    cancelWorkflowRun: [\"POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel\"],\n    createOrUpdateEnvironmentSecret: [\"PUT /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}\"],\n    createOrUpdateOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}\"],\n    createOrUpdateRepoSecret: [\"PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    createRegistrationTokenForOrg: [\"POST /orgs/{org}/actions/runners/registration-token\"],\n    createRegistrationTokenForRepo: [\"POST /repos/{owner}/{repo}/actions/runners/registration-token\"],\n    createRemoveTokenForOrg: [\"POST /orgs/{org}/actions/runners/remove-token\"],\n    createRemoveTokenForRepo: [\"POST /repos/{owner}/{repo}/actions/runners/remove-token\"],\n    createWorkflowDispatch: [\"POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches\"],\n    deleteArtifact: [\"DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}\"],\n    deleteEnvironmentSecret: [\"DELETE /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}\"],\n    deleteOrgSecret: [\"DELETE /orgs/{org}/actions/secrets/{secret_name}\"],\n    deleteRepoSecret: [\"DELETE /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    deleteSelfHostedRunnerFromOrg: [\"DELETE /orgs/{org}/actions/runners/{runner_id}\"],\n    deleteSelfHostedRunnerFromRepo: [\"DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}\"],\n    deleteWorkflowRun: [\"DELETE /repos/{owner}/{repo}/actions/runs/{run_id}\"],\n    deleteWorkflowRunLogs: [\"DELETE /repos/{owner}/{repo}/actions/runs/{run_id}/logs\"],\n    disableSelectedRepositoryGithubActionsOrganization: [\"DELETE /orgs/{org}/actions/permissions/repositories/{repository_id}\"],\n    disableWorkflow: [\"PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable\"],\n    downloadArtifact: [\"GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}\"],\n    downloadJobLogsForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/jobs/{job_id}/logs\"],\n    downloadWorkflowRunLogs: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs\"],\n    enableSelectedRepositoryGithubActionsOrganization: [\"PUT /orgs/{org}/actions/permissions/repositories/{repository_id}\"],\n    enableWorkflow: [\"PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable\"],\n    getAllowedActionsOrganization: [\"GET /orgs/{org}/actions/permissions/selected-actions\"],\n    getAllowedActionsRepository: [\"GET /repos/{owner}/{repo}/actions/permissions/selected-actions\"],\n    getArtifact: [\"GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}\"],\n    getEnvironmentPublicKey: [\"GET /repositories/{repository_id}/environments/{environment_name}/secrets/public-key\"],\n    getEnvironmentSecret: [\"GET /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}\"],\n    getGithubActionsPermissionsOrganization: [\"GET /orgs/{org}/actions/permissions\"],\n    getGithubActionsPermissionsRepository: [\"GET /repos/{owner}/{repo}/actions/permissions\"],\n    getJobForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/jobs/{job_id}\"],\n    getOrgPublicKey: [\"GET /orgs/{org}/actions/secrets/public-key\"],\n    getOrgSecret: [\"GET /orgs/{org}/actions/secrets/{secret_name}\"],\n    getPendingDeploymentsForRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments\"],\n    getRepoPermissions: [\"GET /repos/{owner}/{repo}/actions/permissions\", {}, {\n      renamed: [\"actions\", \"getGithubActionsPermissionsRepository\"]\n    }],\n    getRepoPublicKey: [\"GET /repos/{owner}/{repo}/actions/secrets/public-key\"],\n    getRepoSecret: [\"GET /repos/{owner}/{repo}/actions/secrets/{secret_name}\"],\n    getReviewsForRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/approvals\"],\n    getSelfHostedRunnerForOrg: [\"GET /orgs/{org}/actions/runners/{runner_id}\"],\n    getSelfHostedRunnerForRepo: [\"GET /repos/{owner}/{repo}/actions/runners/{runner_id}\"],\n    getWorkflow: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}\"],\n    getWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}\"],\n    getWorkflowRunUsage: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/timing\"],\n    getWorkflowUsage: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing\"],\n    listArtifactsForRepo: [\"GET /repos/{owner}/{repo}/actions/artifacts\"],\n    listEnvironmentSecrets: [\"GET /repositories/{repository_id}/environments/{environment_name}/secrets\"],\n    listJobsForWorkflowRun: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs\"],\n    listOrgSecrets: [\"GET /orgs/{org}/actions/secrets\"],\n    listRepoSecrets: [\"GET /repos/{owner}/{repo}/actions/secrets\"],\n    listRepoWorkflows: [\"GET /repos/{owner}/{repo}/actions/workflows\"],\n    listRunnerApplicationsForOrg: [\"GET /orgs/{org}/actions/runners/downloads\"],\n    listRunnerApplicationsForRepo: [\"GET /repos/{owner}/{repo}/actions/runners/downloads\"],\n    listSelectedReposForOrgSecret: [\"GET /orgs/{org}/actions/secrets/{secret_name}/repositories\"],\n    listSelectedRepositoriesEnabledGithubActionsOrganization: [\"GET /orgs/{org}/actions/permissions/repositories\"],\n    listSelfHostedRunnersForOrg: [\"GET /orgs/{org}/actions/runners\"],\n    listSelfHostedRunnersForRepo: [\"GET /repos/{owner}/{repo}/actions/runners\"],\n    listWorkflowRunArtifacts: [\"GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts\"],\n    listWorkflowRuns: [\"GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs\"],\n    listWorkflowRunsForRepo: [\"GET /repos/{owner}/{repo}/actions/runs\"],\n    reRunWorkflow: [\"POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun\"],\n    removeSelectedRepoFromOrgSecret: [\"DELETE /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}\"],\n    reviewPendingDeploymentsForRun: [\"POST /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments\"],\n    setAllowedActionsOrganization: [\"PUT /orgs/{org}/actions/permissions/selected-actions\"],\n    setAllowedActionsRepository: [\"PUT /repos/{owner}/{repo}/actions/permissions/selected-actions\"],\n    setGithubActionsPermissionsOrganization: [\"PUT /orgs/{org}/actions/permissions\"],\n    setGithubActionsPermissionsRepository: [\"PUT /repos/{owner}/{repo}/actions/permissions\"],\n    setSelectedReposForOrgSecret: [\"PUT /orgs/{org}/actions/secrets/{secret_name}/repositories\"],\n    setSelectedRepositoriesEnabledGithubActionsOrganization: [\"PUT /orgs/{org}/actions/permissions/repositories\"]\n  },\n  activity: {\n    checkRepoIsStarredByAuthenticatedUser: [\"GET /user/starred/{owner}/{repo}\"],\n    deleteRepoSubscription: [\"DELETE /repos/{owner}/{repo}/subscription\"],\n    deleteThreadSubscription: [\"DELETE /notifications/threads/{thread_id}/subscription\"],\n    getFeeds: [\"GET /feeds\"],\n    getRepoSubscription: [\"GET /repos/{owner}/{repo}/subscription\"],\n    getThread: [\"GET /notifications/threads/{thread_id}\"],\n    getThreadSubscriptionForAuthenticatedUser: [\"GET /notifications/threads/{thread_id}/subscription\"],\n    listEventsForAuthenticatedUser: [\"GET /users/{username}/events\"],\n    listNotificationsForAuthenticatedUser: [\"GET /notifications\"],\n    listOrgEventsForAuthenticatedUser: [\"GET /users/{username}/events/orgs/{org}\"],\n    listPublicEvents: [\"GET /events\"],\n    listPublicEventsForRepoNetwork: [\"GET /networks/{owner}/{repo}/events\"],\n    listPublicEventsForUser: [\"GET /users/{username}/events/public\"],\n    listPublicOrgEvents: [\"GET /orgs/{org}/events\"],\n    listReceivedEventsForUser: [\"GET /users/{username}/received_events\"],\n    listReceivedPublicEventsForUser: [\"GET /users/{username}/received_events/public\"],\n    listRepoEvents: [\"GET /repos/{owner}/{repo}/events\"],\n    listRepoNotificationsForAuthenticatedUser: [\"GET /repos/{owner}/{repo}/notifications\"],\n    listReposStarredByAuthenticatedUser: [\"GET /user/starred\"],\n    listReposStarredByUser: [\"GET /users/{username}/starred\"],\n    listReposWatchedByUser: [\"GET /users/{username}/subscriptions\"],\n    listStargazersForRepo: [\"GET /repos/{owner}/{repo}/stargazers\"],\n    listWatchedReposForAuthenticatedUser: [\"GET /user/subscriptions\"],\n    listWatchersForRepo: [\"GET /repos/{owner}/{repo}/subscribers\"],\n    markNotificationsAsRead: [\"PUT /notifications\"],\n    markRepoNotificationsAsRead: [\"PUT /repos/{owner}/{repo}/notifications\"],\n    markThreadAsRead: [\"PATCH /notifications/threads/{thread_id}\"],\n    setRepoSubscription: [\"PUT /repos/{owner}/{repo}/subscription\"],\n    setThreadSubscription: [\"PUT /notifications/threads/{thread_id}/subscription\"],\n    starRepoForAuthenticatedUser: [\"PUT /user/starred/{owner}/{repo}\"],\n    unstarRepoForAuthenticatedUser: [\"DELETE /user/starred/{owner}/{repo}\"]\n  },\n  apps: {\n    addRepoToInstallation: [\"PUT /user/installations/{installation_id}/repositories/{repository_id}\"],\n    checkToken: [\"POST /applications/{client_id}/token\"],\n    createContentAttachment: [\"POST /content_references/{content_reference_id}/attachments\", {\n      mediaType: {\n        previews: [\"corsair\"]\n      }\n    }],\n    createFromManifest: [\"POST /app-manifests/{code}/conversions\"],\n    createInstallationAccessToken: [\"POST /app/installations/{installation_id}/access_tokens\"],\n    deleteAuthorization: [\"DELETE /applications/{client_id}/grant\"],\n    deleteInstallation: [\"DELETE /app/installations/{installation_id}\"],\n    deleteToken: [\"DELETE /applications/{client_id}/token\"],\n    getAuthenticated: [\"GET /app\"],\n    getBySlug: [\"GET /apps/{app_slug}\"],\n    getInstallation: [\"GET /app/installations/{installation_id}\"],\n    getOrgInstallation: [\"GET /orgs/{org}/installation\"],\n    getRepoInstallation: [\"GET /repos/{owner}/{repo}/installation\"],\n    getSubscriptionPlanForAccount: [\"GET /marketplace_listing/accounts/{account_id}\"],\n    getSubscriptionPlanForAccountStubbed: [\"GET /marketplace_listing/stubbed/accounts/{account_id}\"],\n    getUserInstallation: [\"GET /users/{username}/installation\"],\n    getWebhookConfigForApp: [\"GET /app/hook/config\"],\n    listAccountsForPlan: [\"GET /marketplace_listing/plans/{plan_id}/accounts\"],\n    listAccountsForPlanStubbed: [\"GET /marketplace_listing/stubbed/plans/{plan_id}/accounts\"],\n    listInstallationReposForAuthenticatedUser: [\"GET /user/installations/{installation_id}/repositories\"],\n    listInstallations: [\"GET /app/installations\"],\n    listInstallationsForAuthenticatedUser: [\"GET /user/installations\"],\n    listPlans: [\"GET /marketplace_listing/plans\"],\n    listPlansStubbed: [\"GET /marketplace_listing/stubbed/plans\"],\n    listReposAccessibleToInstallation: [\"GET /installation/repositories\"],\n    listSubscriptionsForAuthenticatedUser: [\"GET /user/marketplace_purchases\"],\n    listSubscriptionsForAuthenticatedUserStubbed: [\"GET /user/marketplace_purchases/stubbed\"],\n    removeRepoFromInstallation: [\"DELETE /user/installations/{installation_id}/repositories/{repository_id}\"],\n    resetToken: [\"PATCH /applications/{client_id}/token\"],\n    revokeInstallationAccessToken: [\"DELETE /installation/token\"],\n    scopeToken: [\"POST /applications/{client_id}/token/scoped\"],\n    suspendInstallation: [\"PUT /app/installations/{installation_id}/suspended\"],\n    unsuspendInstallation: [\"DELETE /app/installations/{installation_id}/suspended\"],\n    updateWebhookConfigForApp: [\"PATCH /app/hook/config\"]\n  },\n  billing: {\n    getGithubActionsBillingOrg: [\"GET /orgs/{org}/settings/billing/actions\"],\n    getGithubActionsBillingUser: [\"GET /users/{username}/settings/billing/actions\"],\n    getGithubPackagesBillingOrg: [\"GET /orgs/{org}/settings/billing/packages\"],\n    getGithubPackagesBillingUser: [\"GET /users/{username}/settings/billing/packages\"],\n    getSharedStorageBillingOrg: [\"GET /orgs/{org}/settings/billing/shared-storage\"],\n    getSharedStorageBillingUser: [\"GET /users/{username}/settings/billing/shared-storage\"]\n  },\n  checks: {\n    create: [\"POST /repos/{owner}/{repo}/check-runs\"],\n    createSuite: [\"POST /repos/{owner}/{repo}/check-suites\"],\n    get: [\"GET /repos/{owner}/{repo}/check-runs/{check_run_id}\"],\n    getSuite: [\"GET /repos/{owner}/{repo}/check-suites/{check_suite_id}\"],\n    listAnnotations: [\"GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations\"],\n    listForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/check-runs\"],\n    listForSuite: [\"GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs\"],\n    listSuitesForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/check-suites\"],\n    rerequestSuite: [\"POST /repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest\"],\n    setSuitesPreferences: [\"PATCH /repos/{owner}/{repo}/check-suites/preferences\"],\n    update: [\"PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}\"]\n  },\n  codeScanning: {\n    deleteAnalysis: [\"DELETE /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}{?confirm_delete}\"],\n    getAlert: [\"GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}\", {}, {\n      renamedParameters: {\n        alert_id: \"alert_number\"\n      }\n    }],\n    getAnalysis: [\"GET /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}\"],\n    getSarif: [\"GET /repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}\"],\n    listAlertsForRepo: [\"GET /repos/{owner}/{repo}/code-scanning/alerts\"],\n    listAlertsInstances: [\"GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances\"],\n    listRecentAnalyses: [\"GET /repos/{owner}/{repo}/code-scanning/analyses\"],\n    updateAlert: [\"PATCH /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}\"],\n    uploadSarif: [\"POST /repos/{owner}/{repo}/code-scanning/sarifs\"]\n  },\n  codesOfConduct: {\n    getAllCodesOfConduct: [\"GET /codes_of_conduct\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }],\n    getConductCode: [\"GET /codes_of_conduct/{key}\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }],\n    getForRepo: [\"GET /repos/{owner}/{repo}/community/code_of_conduct\", {\n      mediaType: {\n        previews: [\"scarlet-witch\"]\n      }\n    }]\n  },\n  emojis: {\n    get: [\"GET /emojis\"]\n  },\n  enterpriseAdmin: {\n    disableSelectedOrganizationGithubActionsEnterprise: [\"DELETE /enterprises/{enterprise}/actions/permissions/organizations/{org_id}\"],\n    enableSelectedOrganizationGithubActionsEnterprise: [\"PUT /enterprises/{enterprise}/actions/permissions/organizations/{org_id}\"],\n    getAllowedActionsEnterprise: [\"GET /enterprises/{enterprise}/actions/permissions/selected-actions\"],\n    getGithubActionsPermissionsEnterprise: [\"GET /enterprises/{enterprise}/actions/permissions\"],\n    listSelectedOrganizationsEnabledGithubActionsEnterprise: [\"GET /enterprises/{enterprise}/actions/permissions/organizations\"],\n    setAllowedActionsEnterprise: [\"PUT /enterprises/{enterprise}/actions/permissions/selected-actions\"],\n    setGithubActionsPermissionsEnterprise: [\"PUT /enterprises/{enterprise}/actions/permissions\"],\n    setSelectedOrganizationsEnabledGithubActionsEnterprise: [\"PUT /enterprises/{enterprise}/actions/permissions/organizations\"]\n  },\n  gists: {\n    checkIsStarred: [\"GET /gists/{gist_id}/star\"],\n    create: [\"POST /gists\"],\n    createComment: [\"POST /gists/{gist_id}/comments\"],\n    delete: [\"DELETE /gists/{gist_id}\"],\n    deleteComment: [\"DELETE /gists/{gist_id}/comments/{comment_id}\"],\n    fork: [\"POST /gists/{gist_id}/forks\"],\n    get: [\"GET /gists/{gist_id}\"],\n    getComment: [\"GET /gists/{gist_id}/comments/{comment_id}\"],\n    getRevision: [\"GET /gists/{gist_id}/{sha}\"],\n    list: [\"GET /gists\"],\n    listComments: [\"GET /gists/{gist_id}/comments\"],\n    listCommits: [\"GET /gists/{gist_id}/commits\"],\n    listForUser: [\"GET /users/{username}/gists\"],\n    listForks: [\"GET /gists/{gist_id}/forks\"],\n    listPublic: [\"GET /gists/public\"],\n    listStarred: [\"GET /gists/starred\"],\n    star: [\"PUT /gists/{gist_id}/star\"],\n    unstar: [\"DELETE /gists/{gist_id}/star\"],\n    update: [\"PATCH /gists/{gist_id}\"],\n    updateComment: [\"PATCH /gists/{gist_id}/comments/{comment_id}\"]\n  },\n  git: {\n    createBlob: [\"POST /repos/{owner}/{repo}/git/blobs\"],\n    createCommit: [\"POST /repos/{owner}/{repo}/git/commits\"],\n    createRef: [\"POST /repos/{owner}/{repo}/git/refs\"],\n    createTag: [\"POST /repos/{owner}/{repo}/git/tags\"],\n    createTree: [\"POST /repos/{owner}/{repo}/git/trees\"],\n    deleteRef: [\"DELETE /repos/{owner}/{repo}/git/refs/{ref}\"],\n    getBlob: [\"GET /repos/{owner}/{repo}/git/blobs/{file_sha}\"],\n    getCommit: [\"GET /repos/{owner}/{repo}/git/commits/{commit_sha}\"],\n    getRef: [\"GET /repos/{owner}/{repo}/git/ref/{ref}\"],\n    getTag: [\"GET /repos/{owner}/{repo}/git/tags/{tag_sha}\"],\n    getTree: [\"GET /repos/{owner}/{repo}/git/trees/{tree_sha}\"],\n    listMatchingRefs: [\"GET /repos/{owner}/{repo}/git/matching-refs/{ref}\"],\n    updateRef: [\"PATCH /repos/{owner}/{repo}/git/refs/{ref}\"]\n  },\n  gitignore: {\n    getAllTemplates: [\"GET /gitignore/templates\"],\n    getTemplate: [\"GET /gitignore/templates/{name}\"]\n  },\n  interactions: {\n    getRestrictionsForAuthenticatedUser: [\"GET /user/interaction-limits\"],\n    getRestrictionsForOrg: [\"GET /orgs/{org}/interaction-limits\"],\n    getRestrictionsForRepo: [\"GET /repos/{owner}/{repo}/interaction-limits\"],\n    getRestrictionsForYourPublicRepos: [\"GET /user/interaction-limits\", {}, {\n      renamed: [\"interactions\", \"getRestrictionsForAuthenticatedUser\"]\n    }],\n    removeRestrictionsForAuthenticatedUser: [\"DELETE /user/interaction-limits\"],\n    removeRestrictionsForOrg: [\"DELETE /orgs/{org}/interaction-limits\"],\n    removeRestrictionsForRepo: [\"DELETE /repos/{owner}/{repo}/interaction-limits\"],\n    removeRestrictionsForYourPublicRepos: [\"DELETE /user/interaction-limits\", {}, {\n      renamed: [\"interactions\", \"removeRestrictionsForAuthenticatedUser\"]\n    }],\n    setRestrictionsForAuthenticatedUser: [\"PUT /user/interaction-limits\"],\n    setRestrictionsForOrg: [\"PUT /orgs/{org}/interaction-limits\"],\n    setRestrictionsForRepo: [\"PUT /repos/{owner}/{repo}/interaction-limits\"],\n    setRestrictionsForYourPublicRepos: [\"PUT /user/interaction-limits\", {}, {\n      renamed: [\"interactions\", \"setRestrictionsForAuthenticatedUser\"]\n    }]\n  },\n  issues: {\n    addAssignees: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/assignees\"],\n    addLabels: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    checkUserCanBeAssigned: [\"GET /repos/{owner}/{repo}/assignees/{assignee}\"],\n    create: [\"POST /repos/{owner}/{repo}/issues\"],\n    createComment: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/comments\"],\n    createLabel: [\"POST /repos/{owner}/{repo}/labels\"],\n    createMilestone: [\"POST /repos/{owner}/{repo}/milestones\"],\n    deleteComment: [\"DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    deleteLabel: [\"DELETE /repos/{owner}/{repo}/labels/{name}\"],\n    deleteMilestone: [\"DELETE /repos/{owner}/{repo}/milestones/{milestone_number}\"],\n    get: [\"GET /repos/{owner}/{repo}/issues/{issue_number}\"],\n    getComment: [\"GET /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    getEvent: [\"GET /repos/{owner}/{repo}/issues/events/{event_id}\"],\n    getLabel: [\"GET /repos/{owner}/{repo}/labels/{name}\"],\n    getMilestone: [\"GET /repos/{owner}/{repo}/milestones/{milestone_number}\"],\n    list: [\"GET /issues\"],\n    listAssignees: [\"GET /repos/{owner}/{repo}/assignees\"],\n    listComments: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/comments\"],\n    listCommentsForRepo: [\"GET /repos/{owner}/{repo}/issues/comments\"],\n    listEvents: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/events\"],\n    listEventsForRepo: [\"GET /repos/{owner}/{repo}/issues/events\"],\n    listEventsForTimeline: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/timeline\", {\n      mediaType: {\n        previews: [\"mockingbird\"]\n      }\n    }],\n    listForAuthenticatedUser: [\"GET /user/issues\"],\n    listForOrg: [\"GET /orgs/{org}/issues\"],\n    listForRepo: [\"GET /repos/{owner}/{repo}/issues\"],\n    listLabelsForMilestone: [\"GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels\"],\n    listLabelsForRepo: [\"GET /repos/{owner}/{repo}/labels\"],\n    listLabelsOnIssue: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    listMilestones: [\"GET /repos/{owner}/{repo}/milestones\"],\n    lock: [\"PUT /repos/{owner}/{repo}/issues/{issue_number}/lock\"],\n    removeAllLabels: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    removeAssignees: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/assignees\"],\n    removeLabel: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}\"],\n    setLabels: [\"PUT /repos/{owner}/{repo}/issues/{issue_number}/labels\"],\n    unlock: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/lock\"],\n    update: [\"PATCH /repos/{owner}/{repo}/issues/{issue_number}\"],\n    updateComment: [\"PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}\"],\n    updateLabel: [\"PATCH /repos/{owner}/{repo}/labels/{name}\"],\n    updateMilestone: [\"PATCH /repos/{owner}/{repo}/milestones/{milestone_number}\"]\n  },\n  licenses: {\n    get: [\"GET /licenses/{license}\"],\n    getAllCommonlyUsed: [\"GET /licenses\"],\n    getForRepo: [\"GET /repos/{owner}/{repo}/license\"]\n  },\n  markdown: {\n    render: [\"POST /markdown\"],\n    renderRaw: [\"POST /markdown/raw\", {\n      headers: {\n        \"content-type\": \"text/plain; charset=utf-8\"\n      }\n    }]\n  },\n  meta: {\n    get: [\"GET /meta\"],\n    getOctocat: [\"GET /octocat\"],\n    getZen: [\"GET /zen\"],\n    root: [\"GET /\"]\n  },\n  migrations: {\n    cancelImport: [\"DELETE /repos/{owner}/{repo}/import\"],\n    deleteArchiveForAuthenticatedUser: [\"DELETE /user/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    deleteArchiveForOrg: [\"DELETE /orgs/{org}/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    downloadArchiveForOrg: [\"GET /orgs/{org}/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getArchiveForAuthenticatedUser: [\"GET /user/migrations/{migration_id}/archive\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getCommitAuthors: [\"GET /repos/{owner}/{repo}/import/authors\"],\n    getImportStatus: [\"GET /repos/{owner}/{repo}/import\"],\n    getLargeFiles: [\"GET /repos/{owner}/{repo}/import/large_files\"],\n    getStatusForAuthenticatedUser: [\"GET /user/migrations/{migration_id}\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    getStatusForOrg: [\"GET /orgs/{org}/migrations/{migration_id}\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listForAuthenticatedUser: [\"GET /user/migrations\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listForOrg: [\"GET /orgs/{org}/migrations\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listReposForOrg: [\"GET /orgs/{org}/migrations/{migration_id}/repositories\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    listReposForUser: [\"GET /user/migrations/{migration_id}/repositories\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    mapCommitAuthor: [\"PATCH /repos/{owner}/{repo}/import/authors/{author_id}\"],\n    setLfsPreference: [\"PATCH /repos/{owner}/{repo}/import/lfs\"],\n    startForAuthenticatedUser: [\"POST /user/migrations\"],\n    startForOrg: [\"POST /orgs/{org}/migrations\"],\n    startImport: [\"PUT /repos/{owner}/{repo}/import\"],\n    unlockRepoForAuthenticatedUser: [\"DELETE /user/migrations/{migration_id}/repos/{repo_name}/lock\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    unlockRepoForOrg: [\"DELETE /orgs/{org}/migrations/{migration_id}/repos/{repo_name}/lock\", {\n      mediaType: {\n        previews: [\"wyandotte\"]\n      }\n    }],\n    updateImport: [\"PATCH /repos/{owner}/{repo}/import\"]\n  },\n  orgs: {\n    blockUser: [\"PUT /orgs/{org}/blocks/{username}\"],\n    cancelInvitation: [\"DELETE /orgs/{org}/invitations/{invitation_id}\"],\n    checkBlockedUser: [\"GET /orgs/{org}/blocks/{username}\"],\n    checkMembershipForUser: [\"GET /orgs/{org}/members/{username}\"],\n    checkPublicMembershipForUser: [\"GET /orgs/{org}/public_members/{username}\"],\n    convertMemberToOutsideCollaborator: [\"PUT /orgs/{org}/outside_collaborators/{username}\"],\n    createInvitation: [\"POST /orgs/{org}/invitations\"],\n    createWebhook: [\"POST /orgs/{org}/hooks\"],\n    deleteWebhook: [\"DELETE /orgs/{org}/hooks/{hook_id}\"],\n    get: [\"GET /orgs/{org}\"],\n    getMembershipForAuthenticatedUser: [\"GET /user/memberships/orgs/{org}\"],\n    getMembershipForUser: [\"GET /orgs/{org}/memberships/{username}\"],\n    getWebhook: [\"GET /orgs/{org}/hooks/{hook_id}\"],\n    getWebhookConfigForOrg: [\"GET /orgs/{org}/hooks/{hook_id}/config\"],\n    list: [\"GET /organizations\"],\n    listAppInstallations: [\"GET /orgs/{org}/installations\"],\n    listBlockedUsers: [\"GET /orgs/{org}/blocks\"],\n    listFailedInvitations: [\"GET /orgs/{org}/failed_invitations\"],\n    listForAuthenticatedUser: [\"GET /user/orgs\"],\n    listForUser: [\"GET /users/{username}/orgs\"],\n    listInvitationTeams: [\"GET /orgs/{org}/invitations/{invitation_id}/teams\"],\n    listMembers: [\"GET /orgs/{org}/members\"],\n    listMembershipsForAuthenticatedUser: [\"GET /user/memberships/orgs\"],\n    listOutsideCollaborators: [\"GET /orgs/{org}/outside_collaborators\"],\n    listPendingInvitations: [\"GET /orgs/{org}/invitations\"],\n    listPublicMembers: [\"GET /orgs/{org}/public_members\"],\n    listWebhooks: [\"GET /orgs/{org}/hooks\"],\n    pingWebhook: [\"POST /orgs/{org}/hooks/{hook_id}/pings\"],\n    removeMember: [\"DELETE /orgs/{org}/members/{username}\"],\n    removeMembershipForUser: [\"DELETE /orgs/{org}/memberships/{username}\"],\n    removeOutsideCollaborator: [\"DELETE /orgs/{org}/outside_collaborators/{username}\"],\n    removePublicMembershipForAuthenticatedUser: [\"DELETE /orgs/{org}/public_members/{username}\"],\n    setMembershipForUser: [\"PUT /orgs/{org}/memberships/{username}\"],\n    setPublicMembershipForAuthenticatedUser: [\"PUT /orgs/{org}/public_members/{username}\"],\n    unblockUser: [\"DELETE /orgs/{org}/blocks/{username}\"],\n    update: [\"PATCH /orgs/{org}\"],\n    updateMembershipForAuthenticatedUser: [\"PATCH /user/memberships/orgs/{org}\"],\n    updateWebhook: [\"PATCH /orgs/{org}/hooks/{hook_id}\"],\n    updateWebhookConfigForOrg: [\"PATCH /orgs/{org}/hooks/{hook_id}/config\"]\n  },\n  packages: {\n    deletePackageForAuthenticatedUser: [\"DELETE /user/packages/{package_type}/{package_name}\"],\n    deletePackageForOrg: [\"DELETE /orgs/{org}/packages/{package_type}/{package_name}\"],\n    deletePackageVersionForAuthenticatedUser: [\"DELETE /user/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    deletePackageVersionForOrg: [\"DELETE /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    getAllPackageVersionsForAPackageOwnedByAnOrg: [\"GET /orgs/{org}/packages/{package_type}/{package_name}/versions\", {}, {\n      renamed: [\"packages\", \"getAllPackageVersionsForPackageOwnedByOrg\"]\n    }],\n    getAllPackageVersionsForAPackageOwnedByTheAuthenticatedUser: [\"GET /user/packages/{package_type}/{package_name}/versions\", {}, {\n      renamed: [\"packages\", \"getAllPackageVersionsForPackageOwnedByAuthenticatedUser\"]\n    }],\n    getAllPackageVersionsForPackageOwnedByAuthenticatedUser: [\"GET /user/packages/{package_type}/{package_name}/versions\"],\n    getAllPackageVersionsForPackageOwnedByOrg: [\"GET /orgs/{org}/packages/{package_type}/{package_name}/versions\"],\n    getAllPackageVersionsForPackageOwnedByUser: [\"GET /users/{username}/packages/{package_type}/{package_name}/versions\"],\n    getPackageForAuthenticatedUser: [\"GET /user/packages/{package_type}/{package_name}\"],\n    getPackageForOrganization: [\"GET /orgs/{org}/packages/{package_type}/{package_name}\"],\n    getPackageForUser: [\"GET /users/{username}/packages/{package_type}/{package_name}\"],\n    getPackageVersionForAuthenticatedUser: [\"GET /user/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    getPackageVersionForOrganization: [\"GET /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    getPackageVersionForUser: [\"GET /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}\"],\n    restorePackageForAuthenticatedUser: [\"POST /user/packages/{package_type}/{package_name}/restore{?token}\"],\n    restorePackageForOrg: [\"POST /orgs/{org}/packages/{package_type}/{package_name}/restore{?token}\"],\n    restorePackageVersionForAuthenticatedUser: [\"POST /user/packages/{package_type}/{package_name}/versions/{package_version_id}/restore\"],\n    restorePackageVersionForOrg: [\"POST /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore\"]\n  },\n  projects: {\n    addCollaborator: [\"PUT /projects/{project_id}/collaborators/{username}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createCard: [\"POST /projects/columns/{column_id}/cards\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createColumn: [\"POST /projects/{project_id}/columns\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForAuthenticatedUser: [\"POST /user/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForOrg: [\"POST /orgs/{org}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    createForRepo: [\"POST /repos/{owner}/{repo}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    delete: [\"DELETE /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    deleteCard: [\"DELETE /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    deleteColumn: [\"DELETE /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    get: [\"GET /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getCard: [\"GET /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getColumn: [\"GET /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    getPermissionForUser: [\"GET /projects/{project_id}/collaborators/{username}/permission\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listCards: [\"GET /projects/columns/{column_id}/cards\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listCollaborators: [\"GET /projects/{project_id}/collaborators\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listColumns: [\"GET /projects/{project_id}/columns\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForOrg: [\"GET /orgs/{org}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForRepo: [\"GET /repos/{owner}/{repo}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listForUser: [\"GET /users/{username}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    moveCard: [\"POST /projects/columns/cards/{card_id}/moves\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    moveColumn: [\"POST /projects/columns/{column_id}/moves\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    removeCollaborator: [\"DELETE /projects/{project_id}/collaborators/{username}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    update: [\"PATCH /projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    updateCard: [\"PATCH /projects/columns/cards/{card_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    updateColumn: [\"PATCH /projects/columns/{column_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }]\n  },\n  pulls: {\n    checkIfMerged: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/merge\"],\n    create: [\"POST /repos/{owner}/{repo}/pulls\"],\n    createReplyForReviewComment: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies\"],\n    createReview: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews\"],\n    createReviewComment: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/comments\"],\n    deletePendingReview: [\"DELETE /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    deleteReviewComment: [\"DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}\"],\n    dismissReview: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals\"],\n    get: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}\"],\n    getReview: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    getReviewComment: [\"GET /repos/{owner}/{repo}/pulls/comments/{comment_id}\"],\n    list: [\"GET /repos/{owner}/{repo}/pulls\"],\n    listCommentsForReview: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments\"],\n    listCommits: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/commits\"],\n    listFiles: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\"],\n    listRequestedReviewers: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    listReviewComments: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/comments\"],\n    listReviewCommentsForRepo: [\"GET /repos/{owner}/{repo}/pulls/comments\"],\n    listReviews: [\"GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews\"],\n    merge: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge\"],\n    removeRequestedReviewers: [\"DELETE /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    requestReviewers: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers\"],\n    submitReview: [\"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/events\"],\n    update: [\"PATCH /repos/{owner}/{repo}/pulls/{pull_number}\"],\n    updateBranch: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch\", {\n      mediaType: {\n        previews: [\"lydian\"]\n      }\n    }],\n    updateReview: [\"PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}\"],\n    updateReviewComment: [\"PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}\"]\n  },\n  rateLimit: {\n    get: [\"GET /rate_limit\"]\n  },\n  reactions: {\n    createForCommitComment: [\"POST /repos/{owner}/{repo}/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForIssue: [\"POST /repos/{owner}/{repo}/issues/{issue_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForIssueComment: [\"POST /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForPullRequestReviewComment: [\"POST /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForTeamDiscussionCommentInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    createForTeamDiscussionInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForCommitComment: [\"DELETE /repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForIssue: [\"DELETE /repos/{owner}/{repo}/issues/{issue_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForIssueComment: [\"DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForPullRequestComment: [\"DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForTeamDiscussion: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteForTeamDiscussionComment: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    deleteLegacy: [\"DELETE /reactions/{reaction_id}\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }, {\n      deprecated: \"octokit.rest.reactions.deleteLegacy() is deprecated, see https://docs.github.com/rest/reference/reactions/#delete-a-reaction-legacy\"\n    }],\n    listForCommitComment: [\"GET /repos/{owner}/{repo}/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForIssue: [\"GET /repos/{owner}/{repo}/issues/{issue_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForIssueComment: [\"GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForPullRequestReviewComment: [\"GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForTeamDiscussionCommentInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }],\n    listForTeamDiscussionInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions\", {\n      mediaType: {\n        previews: [\"squirrel-girl\"]\n      }\n    }]\n  },\n  repos: {\n    acceptInvitation: [\"PATCH /user/repository_invitations/{invitation_id}\"],\n    addAppAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    addCollaborator: [\"PUT /repos/{owner}/{repo}/collaborators/{username}\"],\n    addStatusCheckContexts: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    addTeamAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    addUserAccessRestrictions: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    checkCollaborator: [\"GET /repos/{owner}/{repo}/collaborators/{username}\"],\n    checkVulnerabilityAlerts: [\"GET /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    compareCommits: [\"GET /repos/{owner}/{repo}/compare/{base}...{head}\"],\n    createCommitComment: [\"POST /repos/{owner}/{repo}/commits/{commit_sha}/comments\"],\n    createCommitSignatureProtection: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    createCommitStatus: [\"POST /repos/{owner}/{repo}/statuses/{sha}\"],\n    createDeployKey: [\"POST /repos/{owner}/{repo}/keys\"],\n    createDeployment: [\"POST /repos/{owner}/{repo}/deployments\"],\n    createDeploymentStatus: [\"POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses\"],\n    createDispatchEvent: [\"POST /repos/{owner}/{repo}/dispatches\"],\n    createForAuthenticatedUser: [\"POST /user/repos\"],\n    createFork: [\"POST /repos/{owner}/{repo}/forks\"],\n    createInOrg: [\"POST /orgs/{org}/repos\"],\n    createOrUpdateEnvironment: [\"PUT /repos/{owner}/{repo}/environments/{environment_name}\"],\n    createOrUpdateFileContents: [\"PUT /repos/{owner}/{repo}/contents/{path}\"],\n    createPagesSite: [\"POST /repos/{owner}/{repo}/pages\", {\n      mediaType: {\n        previews: [\"switcheroo\"]\n      }\n    }],\n    createRelease: [\"POST /repos/{owner}/{repo}/releases\"],\n    createUsingTemplate: [\"POST /repos/{template_owner}/{template_repo}/generate\", {\n      mediaType: {\n        previews: [\"baptiste\"]\n      }\n    }],\n    createWebhook: [\"POST /repos/{owner}/{repo}/hooks\"],\n    declineInvitation: [\"DELETE /user/repository_invitations/{invitation_id}\"],\n    delete: [\"DELETE /repos/{owner}/{repo}\"],\n    deleteAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions\"],\n    deleteAdminBranchProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    deleteAnEnvironment: [\"DELETE /repos/{owner}/{repo}/environments/{environment_name}\"],\n    deleteBranchProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    deleteCommitComment: [\"DELETE /repos/{owner}/{repo}/comments/{comment_id}\"],\n    deleteCommitSignatureProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    deleteDeployKey: [\"DELETE /repos/{owner}/{repo}/keys/{key_id}\"],\n    deleteDeployment: [\"DELETE /repos/{owner}/{repo}/deployments/{deployment_id}\"],\n    deleteFile: [\"DELETE /repos/{owner}/{repo}/contents/{path}\"],\n    deleteInvitation: [\"DELETE /repos/{owner}/{repo}/invitations/{invitation_id}\"],\n    deletePagesSite: [\"DELETE /repos/{owner}/{repo}/pages\", {\n      mediaType: {\n        previews: [\"switcheroo\"]\n      }\n    }],\n    deletePullRequestReviewProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    deleteRelease: [\"DELETE /repos/{owner}/{repo}/releases/{release_id}\"],\n    deleteReleaseAsset: [\"DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    deleteWebhook: [\"DELETE /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    disableAutomatedSecurityFixes: [\"DELETE /repos/{owner}/{repo}/automated-security-fixes\", {\n      mediaType: {\n        previews: [\"london\"]\n      }\n    }],\n    disableVulnerabilityAlerts: [\"DELETE /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    downloadArchive: [\"GET /repos/{owner}/{repo}/zipball/{ref}\", {}, {\n      renamed: [\"repos\", \"downloadZipballArchive\"]\n    }],\n    downloadTarballArchive: [\"GET /repos/{owner}/{repo}/tarball/{ref}\"],\n    downloadZipballArchive: [\"GET /repos/{owner}/{repo}/zipball/{ref}\"],\n    enableAutomatedSecurityFixes: [\"PUT /repos/{owner}/{repo}/automated-security-fixes\", {\n      mediaType: {\n        previews: [\"london\"]\n      }\n    }],\n    enableVulnerabilityAlerts: [\"PUT /repos/{owner}/{repo}/vulnerability-alerts\", {\n      mediaType: {\n        previews: [\"dorian\"]\n      }\n    }],\n    get: [\"GET /repos/{owner}/{repo}\"],\n    getAccessRestrictions: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions\"],\n    getAdminBranchProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    getAllEnvironments: [\"GET /repos/{owner}/{repo}/environments\"],\n    getAllStatusCheckContexts: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\"],\n    getAllTopics: [\"GET /repos/{owner}/{repo}/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    getAppsWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\"],\n    getBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}\"],\n    getBranchProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    getClones: [\"GET /repos/{owner}/{repo}/traffic/clones\"],\n    getCodeFrequencyStats: [\"GET /repos/{owner}/{repo}/stats/code_frequency\"],\n    getCollaboratorPermissionLevel: [\"GET /repos/{owner}/{repo}/collaborators/{username}/permission\"],\n    getCombinedStatusForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/status\"],\n    getCommit: [\"GET /repos/{owner}/{repo}/commits/{ref}\"],\n    getCommitActivityStats: [\"GET /repos/{owner}/{repo}/stats/commit_activity\"],\n    getCommitComment: [\"GET /repos/{owner}/{repo}/comments/{comment_id}\"],\n    getCommitSignatureProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures\", {\n      mediaType: {\n        previews: [\"zzzax\"]\n      }\n    }],\n    getCommunityProfileMetrics: [\"GET /repos/{owner}/{repo}/community/profile\"],\n    getContent: [\"GET /repos/{owner}/{repo}/contents/{path}\"],\n    getContributorsStats: [\"GET /repos/{owner}/{repo}/stats/contributors\"],\n    getDeployKey: [\"GET /repos/{owner}/{repo}/keys/{key_id}\"],\n    getDeployment: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}\"],\n    getDeploymentStatus: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}\"],\n    getEnvironment: [\"GET /repos/{owner}/{repo}/environments/{environment_name}\"],\n    getLatestPagesBuild: [\"GET /repos/{owner}/{repo}/pages/builds/latest\"],\n    getLatestRelease: [\"GET /repos/{owner}/{repo}/releases/latest\"],\n    getPages: [\"GET /repos/{owner}/{repo}/pages\"],\n    getPagesBuild: [\"GET /repos/{owner}/{repo}/pages/builds/{build_id}\"],\n    getParticipationStats: [\"GET /repos/{owner}/{repo}/stats/participation\"],\n    getPullRequestReviewProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    getPunchCardStats: [\"GET /repos/{owner}/{repo}/stats/punch_card\"],\n    getReadme: [\"GET /repos/{owner}/{repo}/readme\"],\n    getReadmeInDirectory: [\"GET /repos/{owner}/{repo}/readme/{dir}\"],\n    getRelease: [\"GET /repos/{owner}/{repo}/releases/{release_id}\"],\n    getReleaseAsset: [\"GET /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    getReleaseByTag: [\"GET /repos/{owner}/{repo}/releases/tags/{tag}\"],\n    getStatusChecksProtection: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    getTeamsWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\"],\n    getTopPaths: [\"GET /repos/{owner}/{repo}/traffic/popular/paths\"],\n    getTopReferrers: [\"GET /repos/{owner}/{repo}/traffic/popular/referrers\"],\n    getUsersWithAccessToProtectedBranch: [\"GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\"],\n    getViews: [\"GET /repos/{owner}/{repo}/traffic/views\"],\n    getWebhook: [\"GET /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    getWebhookConfigForRepo: [\"GET /repos/{owner}/{repo}/hooks/{hook_id}/config\"],\n    listBranches: [\"GET /repos/{owner}/{repo}/branches\"],\n    listBranchesForHeadCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head\", {\n      mediaType: {\n        previews: [\"groot\"]\n      }\n    }],\n    listCollaborators: [\"GET /repos/{owner}/{repo}/collaborators\"],\n    listCommentsForCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/comments\"],\n    listCommitCommentsForRepo: [\"GET /repos/{owner}/{repo}/comments\"],\n    listCommitStatusesForRef: [\"GET /repos/{owner}/{repo}/commits/{ref}/statuses\"],\n    listCommits: [\"GET /repos/{owner}/{repo}/commits\"],\n    listContributors: [\"GET /repos/{owner}/{repo}/contributors\"],\n    listDeployKeys: [\"GET /repos/{owner}/{repo}/keys\"],\n    listDeploymentStatuses: [\"GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses\"],\n    listDeployments: [\"GET /repos/{owner}/{repo}/deployments\"],\n    listForAuthenticatedUser: [\"GET /user/repos\"],\n    listForOrg: [\"GET /orgs/{org}/repos\"],\n    listForUser: [\"GET /users/{username}/repos\"],\n    listForks: [\"GET /repos/{owner}/{repo}/forks\"],\n    listInvitations: [\"GET /repos/{owner}/{repo}/invitations\"],\n    listInvitationsForAuthenticatedUser: [\"GET /user/repository_invitations\"],\n    listLanguages: [\"GET /repos/{owner}/{repo}/languages\"],\n    listPagesBuilds: [\"GET /repos/{owner}/{repo}/pages/builds\"],\n    listPublic: [\"GET /repositories\"],\n    listPullRequestsAssociatedWithCommit: [\"GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls\", {\n      mediaType: {\n        previews: [\"groot\"]\n      }\n    }],\n    listReleaseAssets: [\"GET /repos/{owner}/{repo}/releases/{release_id}/assets\"],\n    listReleases: [\"GET /repos/{owner}/{repo}/releases\"],\n    listTags: [\"GET /repos/{owner}/{repo}/tags\"],\n    listTeams: [\"GET /repos/{owner}/{repo}/teams\"],\n    listWebhooks: [\"GET /repos/{owner}/{repo}/hooks\"],\n    merge: [\"POST /repos/{owner}/{repo}/merges\"],\n    pingWebhook: [\"POST /repos/{owner}/{repo}/hooks/{hook_id}/pings\"],\n    removeAppAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    removeCollaborator: [\"DELETE /repos/{owner}/{repo}/collaborators/{username}\"],\n    removeStatusCheckContexts: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    removeStatusCheckProtection: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    removeTeamAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    removeUserAccessRestrictions: [\"DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    renameBranch: [\"POST /repos/{owner}/{repo}/branches/{branch}/rename\"],\n    replaceAllTopics: [\"PUT /repos/{owner}/{repo}/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    requestPagesBuild: [\"POST /repos/{owner}/{repo}/pages/builds\"],\n    setAdminBranchProtection: [\"POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins\"],\n    setAppAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps\", {}, {\n      mapToData: \"apps\"\n    }],\n    setStatusCheckContexts: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts\", {}, {\n      mapToData: \"contexts\"\n    }],\n    setTeamAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams\", {}, {\n      mapToData: \"teams\"\n    }],\n    setUserAccessRestrictions: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users\", {}, {\n      mapToData: \"users\"\n    }],\n    testPushWebhook: [\"POST /repos/{owner}/{repo}/hooks/{hook_id}/tests\"],\n    transfer: [\"POST /repos/{owner}/{repo}/transfer\"],\n    update: [\"PATCH /repos/{owner}/{repo}\"],\n    updateBranchProtection: [\"PUT /repos/{owner}/{repo}/branches/{branch}/protection\"],\n    updateCommitComment: [\"PATCH /repos/{owner}/{repo}/comments/{comment_id}\"],\n    updateInformationAboutPagesSite: [\"PUT /repos/{owner}/{repo}/pages\"],\n    updateInvitation: [\"PATCH /repos/{owner}/{repo}/invitations/{invitation_id}\"],\n    updatePullRequestReviewProtection: [\"PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews\"],\n    updateRelease: [\"PATCH /repos/{owner}/{repo}/releases/{release_id}\"],\n    updateReleaseAsset: [\"PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}\"],\n    updateStatusCheckPotection: [\"PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\", {}, {\n      renamed: [\"repos\", \"updateStatusCheckProtection\"]\n    }],\n    updateStatusCheckProtection: [\"PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks\"],\n    updateWebhook: [\"PATCH /repos/{owner}/{repo}/hooks/{hook_id}\"],\n    updateWebhookConfigForRepo: [\"PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config\"],\n    uploadReleaseAsset: [\"POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}\", {\n      baseUrl: \"https://uploads.github.com\"\n    }]\n  },\n  search: {\n    code: [\"GET /search/code\"],\n    commits: [\"GET /search/commits\", {\n      mediaType: {\n        previews: [\"cloak\"]\n      }\n    }],\n    issuesAndPullRequests: [\"GET /search/issues\"],\n    labels: [\"GET /search/labels\"],\n    repos: [\"GET /search/repositories\"],\n    topics: [\"GET /search/topics\", {\n      mediaType: {\n        previews: [\"mercy\"]\n      }\n    }],\n    users: [\"GET /search/users\"]\n  },\n  secretScanning: {\n    getAlert: [\"GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}\"],\n    listAlertsForRepo: [\"GET /repos/{owner}/{repo}/secret-scanning/alerts\"],\n    updateAlert: [\"PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}\"]\n  },\n  teams: {\n    addOrUpdateMembershipForUserInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    addOrUpdateProjectPermissionsInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    addOrUpdateRepoPermissionsInOrg: [\"PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    checkPermissionsForProjectInOrg: [\"GET /orgs/{org}/teams/{team_slug}/projects/{project_id}\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    checkPermissionsForRepoInOrg: [\"GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    create: [\"POST /orgs/{org}/teams\"],\n    createDiscussionCommentInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments\"],\n    createDiscussionInOrg: [\"POST /orgs/{org}/teams/{team_slug}/discussions\"],\n    deleteDiscussionCommentInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    deleteDiscussionInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    deleteInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}\"],\n    getByName: [\"GET /orgs/{org}/teams/{team_slug}\"],\n    getDiscussionCommentInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    getDiscussionInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    getMembershipForUserInOrg: [\"GET /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    list: [\"GET /orgs/{org}/teams\"],\n    listChildInOrg: [\"GET /orgs/{org}/teams/{team_slug}/teams\"],\n    listDiscussionCommentsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments\"],\n    listDiscussionsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/discussions\"],\n    listForAuthenticatedUser: [\"GET /user/teams\"],\n    listMembersInOrg: [\"GET /orgs/{org}/teams/{team_slug}/members\"],\n    listPendingInvitationsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/invitations\"],\n    listProjectsInOrg: [\"GET /orgs/{org}/teams/{team_slug}/projects\", {\n      mediaType: {\n        previews: [\"inertia\"]\n      }\n    }],\n    listReposInOrg: [\"GET /orgs/{org}/teams/{team_slug}/repos\"],\n    removeMembershipForUserInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}\"],\n    removeProjectInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}\"],\n    removeRepoInOrg: [\"DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}\"],\n    updateDiscussionCommentInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}\"],\n    updateDiscussionInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}\"],\n    updateInOrg: [\"PATCH /orgs/{org}/teams/{team_slug}\"]\n  },\n  users: {\n    addEmailForAuthenticated: [\"POST /user/emails\"],\n    block: [\"PUT /user/blocks/{username}\"],\n    checkBlocked: [\"GET /user/blocks/{username}\"],\n    checkFollowingForUser: [\"GET /users/{username}/following/{target_user}\"],\n    checkPersonIsFollowedByAuthenticated: [\"GET /user/following/{username}\"],\n    createGpgKeyForAuthenticated: [\"POST /user/gpg_keys\"],\n    createPublicSshKeyForAuthenticated: [\"POST /user/keys\"],\n    deleteEmailForAuthenticated: [\"DELETE /user/emails\"],\n    deleteGpgKeyForAuthenticated: [\"DELETE /user/gpg_keys/{gpg_key_id}\"],\n    deletePublicSshKeyForAuthenticated: [\"DELETE /user/keys/{key_id}\"],\n    follow: [\"PUT /user/following/{username}\"],\n    getAuthenticated: [\"GET /user\"],\n    getByUsername: [\"GET /users/{username}\"],\n    getContextForUser: [\"GET /users/{username}/hovercard\"],\n    getGpgKeyForAuthenticated: [\"GET /user/gpg_keys/{gpg_key_id}\"],\n    getPublicSshKeyForAuthenticated: [\"GET /user/keys/{key_id}\"],\n    list: [\"GET /users\"],\n    listBlockedByAuthenticated: [\"GET /user/blocks\"],\n    listEmailsForAuthenticated: [\"GET /user/emails\"],\n    listFollowedByAuthenticated: [\"GET /user/following\"],\n    listFollowersForAuthenticatedUser: [\"GET /user/followers\"],\n    listFollowersForUser: [\"GET /users/{username}/followers\"],\n    listFollowingForUser: [\"GET /users/{username}/following\"],\n    listGpgKeysForAuthenticated: [\"GET /user/gpg_keys\"],\n    listGpgKeysForUser: [\"GET /users/{username}/gpg_keys\"],\n    listPublicEmailsForAuthenticated: [\"GET /user/public_emails\"],\n    listPublicKeysForUser: [\"GET /users/{username}/keys\"],\n    listPublicSshKeysForAuthenticated: [\"GET /user/keys\"],\n    setPrimaryEmailVisibilityForAuthenticated: [\"PATCH /user/email/visibility\"],\n    unblock: [\"DELETE /user/blocks/{username}\"],\n    unfollow: [\"DELETE /user/following/{username}\"],\n    updateAuthenticated: [\"PATCH /user\"]\n  }\n};\n\nconst VERSION = \"4.15.1\";\n\nfunction endpointsToMethods(octokit, endpointsMap) {\n  const newMethods = {};\n\n  for (const [scope, endpoints] of Object.entries(endpointsMap)) {\n    for (const [methodName, endpoint] of Object.entries(endpoints)) {\n      const [route, defaults, decorations] = endpoint;\n      const [method, url] = route.split(/ /);\n      const endpointDefaults = Object.assign({\n        method,\n        url\n      }, defaults);\n\n      if (!newMethods[scope]) {\n        newMethods[scope] = {};\n      }\n\n      const scopeMethods = newMethods[scope];\n\n      if (decorations) {\n        scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations);\n        continue;\n      }\n\n      scopeMethods[methodName] = octokit.request.defaults(endpointDefaults);\n    }\n  }\n\n  return newMethods;\n}\n\nfunction decorate(octokit, scope, methodName, defaults, decorations) {\n  const requestWithDefaults = octokit.request.defaults(defaults);\n  /* istanbul ignore next */\n\n  function withDecorations(...args) {\n    // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n    let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData`\n\n    if (decorations.mapToData) {\n      options = Object.assign({}, options, {\n        data: options[decorations.mapToData],\n        [decorations.mapToData]: undefined\n      });\n      return requestWithDefaults(options);\n    }\n\n    if (decorations.renamed) {\n      const [newScope, newMethodName] = decorations.renamed;\n      octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`);\n    }\n\n    if (decorations.deprecated) {\n      octokit.log.warn(decorations.deprecated);\n    }\n\n    if (decorations.renamedParameters) {\n      // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n      const options = requestWithDefaults.endpoint.merge(...args);\n\n      for (const [name, alias] of Object.entries(decorations.renamedParameters)) {\n        if (name in options) {\n          octokit.log.warn(`\"${name}\" parameter is deprecated for \"octokit.${scope}.${methodName}()\". Use \"${alias}\" instead`);\n\n          if (!(alias in options)) {\n            options[alias] = options[name];\n          }\n\n          delete options[name];\n        }\n      }\n\n      return requestWithDefaults(options);\n    } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488\n\n\n    return requestWithDefaults(...args);\n  }\n\n  return Object.assign(withDecorations, requestWithDefaults);\n}\n\nfunction restEndpointMethods(octokit) {\n  const api = endpointsToMethods(octokit, Endpoints);\n  return _objectSpread2(_objectSpread2({}, api), {}, {\n    rest: api\n  });\n}\nrestEndpointMethods.VERSION = VERSION;\n\nexports.restEndpointMethods = restEndpointMethods;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 537:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar deprecation = __webpack_require__(8932);\nvar once = _interopDefault(__webpack_require__(1223));\n\nconst logOnceCode = once(deprecation => console.warn(deprecation));\nconst logOnceHeaders = once(deprecation => console.warn(deprecation));\n/**\n * Error with extra properties to help with debugging\n */\n\nclass RequestError extends Error {\n  constructor(message, statusCode, options) {\n    super(message); // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n\n    this.name = \"HttpError\";\n    this.status = statusCode;\n    let headers;\n\n    if (\"headers\" in options && typeof options.headers !== \"undefined\") {\n      headers = options.headers;\n    }\n\n    if (\"response\" in options) {\n      this.response = options.response;\n      headers = options.response.headers;\n    } // redact request credentials without mutating original request options\n\n\n    const requestCopy = Object.assign({}, options.request);\n\n    if (options.request.headers.authorization) {\n      requestCopy.headers = Object.assign({}, options.request.headers, {\n        authorization: options.request.headers.authorization.replace(/ .*$/, \" [REDACTED]\")\n      });\n    }\n\n    requestCopy.url = requestCopy.url // client_id & client_secret can be passed as URL query parameters to increase rate limit\n    // see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications\n    .replace(/\\bclient_secret=\\w+/g, \"client_secret=[REDACTED]\") // OAuth tokens can be passed as URL query parameters, although it is not recommended\n    // see https://developer.github.com/v3/#oauth2-token-sent-in-a-header\n    .replace(/\\baccess_token=\\w+/g, \"access_token=[REDACTED]\");\n    this.request = requestCopy; // deprecations\n\n    Object.defineProperty(this, \"code\", {\n      get() {\n        logOnceCode(new deprecation.Deprecation(\"[@octokit/request-error] `error.code` is deprecated, use `error.status`.\"));\n        return statusCode;\n      }\n\n    });\n    Object.defineProperty(this, \"headers\", {\n      get() {\n        logOnceHeaders(new deprecation.Deprecation(\"[@octokit/request-error] `error.headers` is deprecated, use `error.response.headers`.\"));\n        return headers || {};\n      }\n\n    });\n  }\n\n}\n\nexports.RequestError = RequestError;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 6234:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar endpoint = __webpack_require__(9440);\nvar universalUserAgent = __webpack_require__(5030);\nvar isPlainObject = __webpack_require__(3287);\nvar nodeFetch = _interopDefault(__webpack_require__(467));\nvar requestError = __webpack_require__(537);\n\nconst VERSION = \"5.6.2\";\n\nfunction getBufferResponse(response) {\n  return response.arrayBuffer();\n}\n\nfunction fetchWrapper(requestOptions) {\n  const log = requestOptions.request && requestOptions.request.log ? requestOptions.request.log : console;\n\n  if (isPlainObject.isPlainObject(requestOptions.body) || Array.isArray(requestOptions.body)) {\n    requestOptions.body = JSON.stringify(requestOptions.body);\n  }\n\n  let headers = {};\n  let status;\n  let url;\n  const fetch = requestOptions.request && requestOptions.request.fetch || nodeFetch;\n  return fetch(requestOptions.url, Object.assign({\n    method: requestOptions.method,\n    body: requestOptions.body,\n    headers: requestOptions.headers,\n    redirect: requestOptions.redirect\n  }, // `requestOptions.request.agent` type is incompatible\n  // see https://github.com/octokit/types.ts/pull/264\n  requestOptions.request)).then(async response => {\n    url = response.url;\n    status = response.status;\n\n    for (const keyAndValue of response.headers) {\n      headers[keyAndValue[0]] = keyAndValue[1];\n    }\n\n    if (\"deprecation\" in headers) {\n      const matches = headers.link && headers.link.match(/<([^>]+)>; rel=\"deprecation\"/);\n      const deprecationLink = matches && matches.pop();\n      log.warn(`[@octokit/request] \"${requestOptions.method} ${requestOptions.url}\" is deprecated. It is scheduled to be removed on ${headers.sunset}${deprecationLink ? `. See ${deprecationLink}` : \"\"}`);\n    }\n\n    if (status === 204 || status === 205) {\n      return;\n    } // GitHub API returns 200 for HEAD requests\n\n\n    if (requestOptions.method === \"HEAD\") {\n      if (status < 400) {\n        return;\n      }\n\n      throw new requestError.RequestError(response.statusText, status, {\n        response: {\n          url,\n          status,\n          headers,\n          data: undefined\n        },\n        request: requestOptions\n      });\n    }\n\n    if (status === 304) {\n      throw new requestError.RequestError(\"Not modified\", status, {\n        response: {\n          url,\n          status,\n          headers,\n          data: await getResponseData(response)\n        },\n        request: requestOptions\n      });\n    }\n\n    if (status >= 400) {\n      const data = await getResponseData(response);\n      const error = new requestError.RequestError(toErrorMessage(data), status, {\n        response: {\n          url,\n          status,\n          headers,\n          data\n        },\n        request: requestOptions\n      });\n      throw error;\n    }\n\n    return getResponseData(response);\n  }).then(data => {\n    return {\n      status,\n      url,\n      headers,\n      data\n    };\n  }).catch(error => {\n    if (error instanceof requestError.RequestError) throw error;\n    throw new requestError.RequestError(error.message, 500, {\n      request: requestOptions\n    });\n  });\n}\n\nasync function getResponseData(response) {\n  const contentType = response.headers.get(\"content-type\");\n\n  if (/application\\/json/.test(contentType)) {\n    return response.json();\n  }\n\n  if (!contentType || /^text\\/|charset=utf-8$/.test(contentType)) {\n    return response.text();\n  }\n\n  return getBufferResponse(response);\n}\n\nfunction toErrorMessage(data) {\n  if (typeof data === \"string\") return data; // istanbul ignore else - just in case\n\n  if (\"message\" in data) {\n    if (Array.isArray(data.errors)) {\n      return `${data.message}: ${data.errors.map(JSON.stringify).join(\", \")}`;\n    }\n\n    return data.message;\n  } // istanbul ignore next - just in case\n\n\n  return `Unknown error: ${JSON.stringify(data)}`;\n}\n\nfunction withDefaults(oldEndpoint, newDefaults) {\n  const endpoint = oldEndpoint.defaults(newDefaults);\n\n  const newApi = function (route, parameters) {\n    const endpointOptions = endpoint.merge(route, parameters);\n\n    if (!endpointOptions.request || !endpointOptions.request.hook) {\n      return fetchWrapper(endpoint.parse(endpointOptions));\n    }\n\n    const request = (route, parameters) => {\n      return fetchWrapper(endpoint.parse(endpoint.merge(route, parameters)));\n    };\n\n    Object.assign(request, {\n      endpoint,\n      defaults: withDefaults.bind(null, endpoint)\n    });\n    return endpointOptions.request.hook(request, endpointOptions);\n  };\n\n  return Object.assign(newApi, {\n    endpoint,\n    defaults: withDefaults.bind(null, endpoint)\n  });\n}\n\nconst request = withDefaults(endpoint.endpoint, {\n  headers: {\n    \"user-agent\": `octokit-request.js/${VERSION} ${universalUserAgent.getUserAgent()}`\n  }\n});\n\nexports.request = request;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 3682:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nvar register = __webpack_require__(4670)\nvar addHook = __webpack_require__(5549)\nvar removeHook = __webpack_require__(6819)\n\n// bind with array of arguments: https://stackoverflow.com/a/21792913\nvar bind = Function.bind\nvar bindable = bind.bind(bind)\n\nfunction bindApi (hook, state, name) {\n  var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state])\n  hook.api = { remove: removeHookRef }\n  hook.remove = removeHookRef\n\n  ;['before', 'error', 'after', 'wrap'].forEach(function (kind) {\n    var args = name ? [state, kind, name] : [state, kind]\n    hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args)\n  })\n}\n\nfunction HookSingular () {\n  var singularHookName = 'h'\n  var singularHookState = {\n    registry: {}\n  }\n  var singularHook = register.bind(null, singularHookState, singularHookName)\n  bindApi(singularHook, singularHookState, singularHookName)\n  return singularHook\n}\n\nfunction HookCollection () {\n  var state = {\n    registry: {}\n  }\n\n  var hook = register.bind(null, state)\n  bindApi(hook, state)\n\n  return hook\n}\n\nvar collectionHookDeprecationMessageDisplayed = false\nfunction Hook () {\n  if (!collectionHookDeprecationMessageDisplayed) {\n    console.warn('[before-after-hook]: \"Hook()\" repurposing warning, use \"Hook.Collection()\". Read more: https://git.io/upgrade-before-after-hook-to-1.4')\n    collectionHookDeprecationMessageDisplayed = true\n  }\n  return HookCollection()\n}\n\nHook.Singular = HookSingular.bind()\nHook.Collection = HookCollection.bind()\n\nmodule.exports = Hook\n// expose constructors as a named property for TypeScript\nmodule.exports.Hook = Hook\nmodule.exports.Singular = Hook.Singular\nmodule.exports.Collection = Hook.Collection\n\n\n/***/ }),\n\n/***/ 5549:\n/***/ ((module) => {\n\nmodule.exports = addHook;\n\nfunction addHook(state, kind, name, hook) {\n  var orig = hook;\n  if (!state.registry[name]) {\n    state.registry[name] = [];\n  }\n\n  if (kind === \"before\") {\n    hook = function (method, options) {\n      return Promise.resolve()\n        .then(orig.bind(null, options))\n        .then(method.bind(null, options));\n    };\n  }\n\n  if (kind === \"after\") {\n    hook = function (method, options) {\n      var result;\n      return Promise.resolve()\n        .then(method.bind(null, options))\n        .then(function (result_) {\n          result = result_;\n          return orig(result, options);\n        })\n        .then(function () {\n          return result;\n        });\n    };\n  }\n\n  if (kind === \"error\") {\n    hook = function (method, options) {\n      return Promise.resolve()\n        .then(method.bind(null, options))\n        .catch(function (error) {\n          return orig(error, options);\n        });\n    };\n  }\n\n  state.registry[name].push({\n    hook: hook,\n    orig: orig,\n  });\n}\n\n\n/***/ }),\n\n/***/ 4670:\n/***/ ((module) => {\n\nmodule.exports = register;\n\nfunction register(state, name, method, options) {\n  if (typeof method !== \"function\") {\n    throw new Error(\"method for before hook must be a function\");\n  }\n\n  if (!options) {\n    options = {};\n  }\n\n  if (Array.isArray(name)) {\n    return name.reverse().reduce(function (callback, name) {\n      return register.bind(null, state, name, callback, options);\n    }, method)();\n  }\n\n  return Promise.resolve().then(function () {\n    if (!state.registry[name]) {\n      return method(options);\n    }\n\n    return state.registry[name].reduce(function (method, registered) {\n      return registered.hook.bind(null, method, options);\n    }, method)();\n  });\n}\n\n\n/***/ }),\n\n/***/ 6819:\n/***/ ((module) => {\n\nmodule.exports = removeHook;\n\nfunction removeHook(state, name, method) {\n  if (!state.registry[name]) {\n    return;\n  }\n\n  var index = state.registry[name]\n    .map(function (registered) {\n      return registered.orig;\n    })\n    .indexOf(method);\n\n  if (index === -1) {\n    return;\n  }\n\n  state.registry[name].splice(index, 1);\n}\n\n\n/***/ }),\n\n/***/ 8932:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nclass Deprecation extends Error {\n  constructor(message) {\n    super(message); // Maintains proper stack trace (only available on V8)\n\n    /* istanbul ignore next */\n\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n\n    this.name = 'Deprecation';\n  }\n\n}\n\nexports.Deprecation = Deprecation;\n\n\n/***/ }),\n\n/***/ 3287:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\n/*!\n * is-plain-object <https://github.com/jonschlinkert/is-plain-object>\n *\n * Copyright (c) 2014-2017, Jon Schlinkert.\n * Released under the MIT License.\n */\n\nfunction isObject(o) {\n  return Object.prototype.toString.call(o) === '[object Object]';\n}\n\nfunction isPlainObject(o) {\n  var ctor,prot;\n\n  if (isObject(o) === false) return false;\n\n  // If has modified constructor\n  ctor = o.constructor;\n  if (ctor === undefined) return true;\n\n  // If has modified prototype\n  prot = ctor.prototype;\n  if (isObject(prot) === false) return false;\n\n  // If constructor does not have an Object-specific method\n  if (prot.hasOwnProperty('isPrototypeOf') === false) {\n    return false;\n  }\n\n  // Most likely a plain Object\n  return true;\n}\n\nexports.isPlainObject = isPlainObject;\n\n\n/***/ }),\n\n/***/ 467:\n/***/ ((module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar Stream = _interopDefault(__webpack_require__(2413));\nvar http = _interopDefault(__webpack_require__(8605));\nvar Url = _interopDefault(__webpack_require__(8835));\nvar whatwgUrl = _interopDefault(__webpack_require__(8665));\nvar https = _interopDefault(__webpack_require__(7211));\nvar zlib = _interopDefault(__webpack_require__(8761));\n\n// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js\n\n// fix for \"Readable\" isn't a named export issue\nconst Readable = Stream.Readable;\n\nconst BUFFER = Symbol('buffer');\nconst TYPE = Symbol('type');\n\nclass Blob {\n\tconstructor() {\n\t\tthis[TYPE] = '';\n\n\t\tconst blobParts = arguments[0];\n\t\tconst options = arguments[1];\n\n\t\tconst buffers = [];\n\t\tlet size = 0;\n\n\t\tif (blobParts) {\n\t\t\tconst a = blobParts;\n\t\t\tconst length = Number(a.length);\n\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\tconst element = a[i];\n\t\t\t\tlet buffer;\n\t\t\t\tif (element instanceof Buffer) {\n\t\t\t\t\tbuffer = element;\n\t\t\t\t} else if (ArrayBuffer.isView(element)) {\n\t\t\t\t\tbuffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);\n\t\t\t\t} else if (element instanceof ArrayBuffer) {\n\t\t\t\t\tbuffer = Buffer.from(element);\n\t\t\t\t} else if (element instanceof Blob) {\n\t\t\t\t\tbuffer = element[BUFFER];\n\t\t\t\t} else {\n\t\t\t\t\tbuffer = Buffer.from(typeof element === 'string' ? element : String(element));\n\t\t\t\t}\n\t\t\t\tsize += buffer.length;\n\t\t\t\tbuffers.push(buffer);\n\t\t\t}\n\t\t}\n\n\t\tthis[BUFFER] = Buffer.concat(buffers);\n\n\t\tlet type = options && options.type !== undefined && String(options.type).toLowerCase();\n\t\tif (type && !/[^\\u0020-\\u007E]/.test(type)) {\n\t\t\tthis[TYPE] = type;\n\t\t}\n\t}\n\tget size() {\n\t\treturn this[BUFFER].length;\n\t}\n\tget type() {\n\t\treturn this[TYPE];\n\t}\n\ttext() {\n\t\treturn Promise.resolve(this[BUFFER].toString());\n\t}\n\tarrayBuffer() {\n\t\tconst buf = this[BUFFER];\n\t\tconst ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n\t\treturn Promise.resolve(ab);\n\t}\n\tstream() {\n\t\tconst readable = new Readable();\n\t\treadable._read = function () {};\n\t\treadable.push(this[BUFFER]);\n\t\treadable.push(null);\n\t\treturn readable;\n\t}\n\ttoString() {\n\t\treturn '[object Blob]';\n\t}\n\tslice() {\n\t\tconst size = this.size;\n\n\t\tconst start = arguments[0];\n\t\tconst end = arguments[1];\n\t\tlet relativeStart, relativeEnd;\n\t\tif (start === undefined) {\n\t\t\trelativeStart = 0;\n\t\t} else if (start < 0) {\n\t\t\trelativeStart = Math.max(size + start, 0);\n\t\t} else {\n\t\t\trelativeStart = Math.min(start, size);\n\t\t}\n\t\tif (end === undefined) {\n\t\t\trelativeEnd = size;\n\t\t} else if (end < 0) {\n\t\t\trelativeEnd = Math.max(size + end, 0);\n\t\t} else {\n\t\t\trelativeEnd = Math.min(end, size);\n\t\t}\n\t\tconst span = Math.max(relativeEnd - relativeStart, 0);\n\n\t\tconst buffer = this[BUFFER];\n\t\tconst slicedBuffer = buffer.slice(relativeStart, relativeStart + span);\n\t\tconst blob = new Blob([], { type: arguments[2] });\n\t\tblob[BUFFER] = slicedBuffer;\n\t\treturn blob;\n\t}\n}\n\nObject.defineProperties(Blob.prototype, {\n\tsize: { enumerable: true },\n\ttype: { enumerable: true },\n\tslice: { enumerable: true }\n});\n\nObject.defineProperty(Blob.prototype, Symbol.toStringTag, {\n\tvalue: 'Blob',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\n/**\n * fetch-error.js\n *\n * FetchError interface for operational errors\n */\n\n/**\n * Create FetchError instance\n *\n * @param   String      message      Error message for human\n * @param   String      type         Error type for machine\n * @param   String      systemError  For Node.js system error\n * @return  FetchError\n */\nfunction FetchError(message, type, systemError) {\n  Error.call(this, message);\n\n  this.message = message;\n  this.type = type;\n\n  // when err.type is `system`, err.code contains system error code\n  if (systemError) {\n    this.code = this.errno = systemError.code;\n  }\n\n  // hide custom error implementation details from end-users\n  Error.captureStackTrace(this, this.constructor);\n}\n\nFetchError.prototype = Object.create(Error.prototype);\nFetchError.prototype.constructor = FetchError;\nFetchError.prototype.name = 'FetchError';\n\nlet convert;\ntry {\n\tconvert = __webpack_require__(2877).convert;\n} catch (e) {}\n\nconst INTERNALS = Symbol('Body internals');\n\n// fix an issue where \"PassThrough\" isn't a named export for node <10\nconst PassThrough = Stream.PassThrough;\n\n/**\n * Body mixin\n *\n * Ref: https://fetch.spec.whatwg.org/#body\n *\n * @param   Stream  body  Readable stream\n * @param   Object  opts  Response options\n * @return  Void\n */\nfunction Body(body) {\n\tvar _this = this;\n\n\tvar _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n\t    _ref$size = _ref.size;\n\n\tlet size = _ref$size === undefined ? 0 : _ref$size;\n\tvar _ref$timeout = _ref.timeout;\n\tlet timeout = _ref$timeout === undefined ? 0 : _ref$timeout;\n\n\tif (body == null) {\n\t\t// body is undefined or null\n\t\tbody = null;\n\t} else if (isURLSearchParams(body)) {\n\t\t// body is a URLSearchParams\n\t\tbody = Buffer.from(body.toString());\n\t} else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {\n\t\t// body is ArrayBuffer\n\t\tbody = Buffer.from(body);\n\t} else if (ArrayBuffer.isView(body)) {\n\t\t// body is ArrayBufferView\n\t\tbody = Buffer.from(body.buffer, body.byteOffset, body.byteLength);\n\t} else if (body instanceof Stream) ; else {\n\t\t// none of the above\n\t\t// coerce to string then buffer\n\t\tbody = Buffer.from(String(body));\n\t}\n\tthis[INTERNALS] = {\n\t\tbody,\n\t\tdisturbed: false,\n\t\terror: null\n\t};\n\tthis.size = size;\n\tthis.timeout = timeout;\n\n\tif (body instanceof Stream) {\n\t\tbody.on('error', function (err) {\n\t\t\tconst error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err);\n\t\t\t_this[INTERNALS].error = error;\n\t\t});\n\t}\n}\n\nBody.prototype = {\n\tget body() {\n\t\treturn this[INTERNALS].body;\n\t},\n\n\tget bodyUsed() {\n\t\treturn this[INTERNALS].disturbed;\n\t},\n\n\t/**\n  * Decode response as ArrayBuffer\n  *\n  * @return  Promise\n  */\n\tarrayBuffer() {\n\t\treturn consumeBody.call(this).then(function (buf) {\n\t\t\treturn buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n\t\t});\n\t},\n\n\t/**\n  * Return raw response as Blob\n  *\n  * @return Promise\n  */\n\tblob() {\n\t\tlet ct = this.headers && this.headers.get('content-type') || '';\n\t\treturn consumeBody.call(this).then(function (buf) {\n\t\t\treturn Object.assign(\n\t\t\t// Prevent copying\n\t\t\tnew Blob([], {\n\t\t\t\ttype: ct.toLowerCase()\n\t\t\t}), {\n\t\t\t\t[BUFFER]: buf\n\t\t\t});\n\t\t});\n\t},\n\n\t/**\n  * Decode response as json\n  *\n  * @return  Promise\n  */\n\tjson() {\n\t\tvar _this2 = this;\n\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buffer.toString());\n\t\t\t} catch (err) {\n\t\t\t\treturn Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n  * Decode response as text\n  *\n  * @return  Promise\n  */\n\ttext() {\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\treturn buffer.toString();\n\t\t});\n\t},\n\n\t/**\n  * Decode response as buffer (non-spec api)\n  *\n  * @return  Promise\n  */\n\tbuffer() {\n\t\treturn consumeBody.call(this);\n\t},\n\n\t/**\n  * Decode response as text, while automatically detecting the encoding and\n  * trying to decode to UTF-8 (non-spec api)\n  *\n  * @return  Promise\n  */\n\ttextConverted() {\n\t\tvar _this3 = this;\n\n\t\treturn consumeBody.call(this).then(function (buffer) {\n\t\t\treturn convertBody(buffer, _this3.headers);\n\t\t});\n\t}\n};\n\n// In browsers, all properties are enumerable.\nObject.defineProperties(Body.prototype, {\n\tbody: { enumerable: true },\n\tbodyUsed: { enumerable: true },\n\tarrayBuffer: { enumerable: true },\n\tblob: { enumerable: true },\n\tjson: { enumerable: true },\n\ttext: { enumerable: true }\n});\n\nBody.mixIn = function (proto) {\n\tfor (const name of Object.getOwnPropertyNames(Body.prototype)) {\n\t\t// istanbul ignore else: future proof\n\t\tif (!(name in proto)) {\n\t\t\tconst desc = Object.getOwnPropertyDescriptor(Body.prototype, name);\n\t\t\tObject.defineProperty(proto, name, desc);\n\t\t}\n\t}\n};\n\n/**\n * Consume and convert an entire Body to a Buffer.\n *\n * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body\n *\n * @return  Promise\n */\nfunction consumeBody() {\n\tvar _this4 = this;\n\n\tif (this[INTERNALS].disturbed) {\n\t\treturn Body.Promise.reject(new TypeError(`body used already for: ${this.url}`));\n\t}\n\n\tthis[INTERNALS].disturbed = true;\n\n\tif (this[INTERNALS].error) {\n\t\treturn Body.Promise.reject(this[INTERNALS].error);\n\t}\n\n\tlet body = this.body;\n\n\t// body is null\n\tif (body === null) {\n\t\treturn Body.Promise.resolve(Buffer.alloc(0));\n\t}\n\n\t// body is blob\n\tif (isBlob(body)) {\n\t\tbody = body.stream();\n\t}\n\n\t// body is buffer\n\tif (Buffer.isBuffer(body)) {\n\t\treturn Body.Promise.resolve(body);\n\t}\n\n\t// istanbul ignore if: should never happen\n\tif (!(body instanceof Stream)) {\n\t\treturn Body.Promise.resolve(Buffer.alloc(0));\n\t}\n\n\t// body is stream\n\t// get ready to actually consume the body\n\tlet accum = [];\n\tlet accumBytes = 0;\n\tlet abort = false;\n\n\treturn new Body.Promise(function (resolve, reject) {\n\t\tlet resTimeout;\n\n\t\t// allow timeout on slow response body\n\t\tif (_this4.timeout) {\n\t\t\tresTimeout = setTimeout(function () {\n\t\t\t\tabort = true;\n\t\t\t\treject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout'));\n\t\t\t}, _this4.timeout);\n\t\t}\n\n\t\t// handle stream errors\n\t\tbody.on('error', function (err) {\n\t\t\tif (err.name === 'AbortError') {\n\t\t\t\t// if the request was aborted, reject with this Error\n\t\t\t\tabort = true;\n\t\t\t\treject(err);\n\t\t\t} else {\n\t\t\t\t// other errors, such as incorrect content-encoding\n\t\t\t\treject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err));\n\t\t\t}\n\t\t});\n\n\t\tbody.on('data', function (chunk) {\n\t\t\tif (abort || chunk === null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (_this4.size && accumBytes + chunk.length > _this4.size) {\n\t\t\t\tabort = true;\n\t\t\t\treject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size'));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\taccumBytes += chunk.length;\n\t\t\taccum.push(chunk);\n\t\t});\n\n\t\tbody.on('end', function () {\n\t\t\tif (abort) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tclearTimeout(resTimeout);\n\n\t\t\ttry {\n\t\t\t\tresolve(Buffer.concat(accum, accumBytes));\n\t\t\t} catch (err) {\n\t\t\t\t// handle streams that have accumulated too much data (issue #414)\n\t\t\t\treject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err));\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Detect buffer encoding and convert to target encoding\n * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding\n *\n * @param   Buffer  buffer    Incoming buffer\n * @param   String  encoding  Target encoding\n * @return  String\n */\nfunction convertBody(buffer, headers) {\n\tif (typeof convert !== 'function') {\n\t\tthrow new Error('The package `encoding` must be installed to use the textConverted() function');\n\t}\n\n\tconst ct = headers.get('content-type');\n\tlet charset = 'utf-8';\n\tlet res, str;\n\n\t// header\n\tif (ct) {\n\t\tres = /charset=([^;]*)/i.exec(ct);\n\t}\n\n\t// no charset in content type, peek at response body for at most 1024 bytes\n\tstr = buffer.slice(0, 1024).toString();\n\n\t// html5\n\tif (!res && str) {\n\t\tres = /<meta.+?charset=(['\"])(.+?)\\1/i.exec(str);\n\t}\n\n\t// html4\n\tif (!res && str) {\n\t\tres = /<meta[\\s]+?http-equiv=(['\"])content-type\\1[\\s]+?content=(['\"])(.+?)\\2/i.exec(str);\n\t\tif (!res) {\n\t\t\tres = /<meta[\\s]+?content=(['\"])(.+?)\\1[\\s]+?http-equiv=(['\"])content-type\\3/i.exec(str);\n\t\t\tif (res) {\n\t\t\t\tres.pop(); // drop last quote\n\t\t\t}\n\t\t}\n\n\t\tif (res) {\n\t\t\tres = /charset=(.*)/i.exec(res.pop());\n\t\t}\n\t}\n\n\t// xml\n\tif (!res && str) {\n\t\tres = /<\\?xml.+?encoding=(['\"])(.+?)\\1/i.exec(str);\n\t}\n\n\t// found charset\n\tif (res) {\n\t\tcharset = res.pop();\n\n\t\t// prevent decode issues when sites use incorrect encoding\n\t\t// ref: https://hsivonen.fi/encoding-menu/\n\t\tif (charset === 'gb2312' || charset === 'gbk') {\n\t\t\tcharset = 'gb18030';\n\t\t}\n\t}\n\n\t// turn raw buffers into a single utf-8 buffer\n\treturn convert(buffer, 'UTF-8', charset).toString();\n}\n\n/**\n * Detect a URLSearchParams object\n * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143\n *\n * @param   Object  obj     Object to detect by type or brand\n * @return  String\n */\nfunction isURLSearchParams(obj) {\n\t// Duck-typing as a necessary condition.\n\tif (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') {\n\t\treturn false;\n\t}\n\n\t// Brand-checking and more duck-typing as optional condition.\n\treturn obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';\n}\n\n/**\n * Check if `obj` is a W3C `Blob` object (which `File` inherits from)\n * @param  {*} obj\n * @return {boolean}\n */\nfunction isBlob(obj) {\n\treturn typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]);\n}\n\n/**\n * Clone body given Res/Req instance\n *\n * @param   Mixed  instance  Response or Request instance\n * @return  Mixed\n */\nfunction clone(instance) {\n\tlet p1, p2;\n\tlet body = instance.body;\n\n\t// don't allow cloning a used body\n\tif (instance.bodyUsed) {\n\t\tthrow new Error('cannot clone body after it is used');\n\t}\n\n\t// check that body is a stream and not form-data object\n\t// note: we can't clone the form-data object without having it as a dependency\n\tif (body instanceof Stream && typeof body.getBoundary !== 'function') {\n\t\t// tee instance body\n\t\tp1 = new PassThrough();\n\t\tp2 = new PassThrough();\n\t\tbody.pipe(p1);\n\t\tbody.pipe(p2);\n\t\t// set instance body to teed body and return the other teed body\n\t\tinstance[INTERNALS].body = p1;\n\t\tbody = p2;\n\t}\n\n\treturn body;\n}\n\n/**\n * Performs the operation \"extract a `Content-Type` value from |object|\" as\n * specified in the specification:\n * https://fetch.spec.whatwg.org/#concept-bodyinit-extract\n *\n * This function assumes that instance.body is present.\n *\n * @param   Mixed  instance  Any options.body input\n */\nfunction extractContentType(body) {\n\tif (body === null) {\n\t\t// body is null\n\t\treturn null;\n\t} else if (typeof body === 'string') {\n\t\t// body is string\n\t\treturn 'text/plain;charset=UTF-8';\n\t} else if (isURLSearchParams(body)) {\n\t\t// body is a URLSearchParams\n\t\treturn 'application/x-www-form-urlencoded;charset=UTF-8';\n\t} else if (isBlob(body)) {\n\t\t// body is blob\n\t\treturn body.type || null;\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\treturn null;\n\t} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {\n\t\t// body is ArrayBuffer\n\t\treturn null;\n\t} else if (ArrayBuffer.isView(body)) {\n\t\t// body is ArrayBufferView\n\t\treturn null;\n\t} else if (typeof body.getBoundary === 'function') {\n\t\t// detect form data input from form-data module\n\t\treturn `multipart/form-data;boundary=${body.getBoundary()}`;\n\t} else if (body instanceof Stream) {\n\t\t// body is stream\n\t\t// can't really do much about this\n\t\treturn null;\n\t} else {\n\t\t// Body constructor defaults other things to string\n\t\treturn 'text/plain;charset=UTF-8';\n\t}\n}\n\n/**\n * The Fetch Standard treats this as if \"total bytes\" is a property on the body.\n * For us, we have to explicitly get it with a function.\n *\n * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes\n *\n * @param   Body    instance   Instance of Body\n * @return  Number?            Number of bytes, or null if not possible\n */\nfunction getTotalBytes(instance) {\n\tconst body = instance.body;\n\n\n\tif (body === null) {\n\t\t// body is null\n\t\treturn 0;\n\t} else if (isBlob(body)) {\n\t\treturn body.size;\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\treturn body.length;\n\t} else if (body && typeof body.getLengthSync === 'function') {\n\t\t// detect form data input from form-data module\n\t\tif (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x\n\t\tbody.hasKnownLength && body.hasKnownLength()) {\n\t\t\t// 2.x\n\t\t\treturn body.getLengthSync();\n\t\t}\n\t\treturn null;\n\t} else {\n\t\t// body is stream\n\t\treturn null;\n\t}\n}\n\n/**\n * Write a Body to a Node.js WritableStream (e.g. http.Request) object.\n *\n * @param   Body    instance   Instance of Body\n * @return  Void\n */\nfunction writeToStream(dest, instance) {\n\tconst body = instance.body;\n\n\n\tif (body === null) {\n\t\t// body is null\n\t\tdest.end();\n\t} else if (isBlob(body)) {\n\t\tbody.stream().pipe(dest);\n\t} else if (Buffer.isBuffer(body)) {\n\t\t// body is buffer\n\t\tdest.write(body);\n\t\tdest.end();\n\t} else {\n\t\t// body is stream\n\t\tbody.pipe(dest);\n\t}\n}\n\n// expose Promise\nBody.Promise = global.Promise;\n\n/**\n * headers.js\n *\n * Headers class offers convenient helpers\n */\n\nconst invalidTokenRegex = /[^\\^_`a-zA-Z\\-0-9!#$%&'*+.|~]/;\nconst invalidHeaderCharRegex = /[^\\t\\x20-\\x7e\\x80-\\xff]/;\n\nfunction validateName(name) {\n\tname = `${name}`;\n\tif (invalidTokenRegex.test(name) || name === '') {\n\t\tthrow new TypeError(`${name} is not a legal HTTP header name`);\n\t}\n}\n\nfunction validateValue(value) {\n\tvalue = `${value}`;\n\tif (invalidHeaderCharRegex.test(value)) {\n\t\tthrow new TypeError(`${value} is not a legal HTTP header value`);\n\t}\n}\n\n/**\n * Find the key in the map object given a header name.\n *\n * Returns undefined if not found.\n *\n * @param   String  name  Header name\n * @return  String|Undefined\n */\nfunction find(map, name) {\n\tname = name.toLowerCase();\n\tfor (const key in map) {\n\t\tif (key.toLowerCase() === name) {\n\t\t\treturn key;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nconst MAP = Symbol('map');\nclass Headers {\n\t/**\n  * Headers class\n  *\n  * @param   Object  headers  Response headers\n  * @return  Void\n  */\n\tconstructor() {\n\t\tlet init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;\n\n\t\tthis[MAP] = Object.create(null);\n\n\t\tif (init instanceof Headers) {\n\t\t\tconst rawHeaders = init.raw();\n\t\t\tconst headerNames = Object.keys(rawHeaders);\n\n\t\t\tfor (const headerName of headerNames) {\n\t\t\t\tfor (const value of rawHeaders[headerName]) {\n\t\t\t\t\tthis.append(headerName, value);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// We don't worry about converting prop to ByteString here as append()\n\t\t// will handle it.\n\t\tif (init == null) ; else if (typeof init === 'object') {\n\t\t\tconst method = init[Symbol.iterator];\n\t\t\tif (method != null) {\n\t\t\t\tif (typeof method !== 'function') {\n\t\t\t\t\tthrow new TypeError('Header pairs must be iterable');\n\t\t\t\t}\n\n\t\t\t\t// sequence<sequence<ByteString>>\n\t\t\t\t// Note: per spec we have to first exhaust the lists then process them\n\t\t\t\tconst pairs = [];\n\t\t\t\tfor (const pair of init) {\n\t\t\t\t\tif (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {\n\t\t\t\t\t\tthrow new TypeError('Each header pair must be iterable');\n\t\t\t\t\t}\n\t\t\t\t\tpairs.push(Array.from(pair));\n\t\t\t\t}\n\n\t\t\t\tfor (const pair of pairs) {\n\t\t\t\t\tif (pair.length !== 2) {\n\t\t\t\t\t\tthrow new TypeError('Each header pair must be a name/value tuple');\n\t\t\t\t\t}\n\t\t\t\t\tthis.append(pair[0], pair[1]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// record<ByteString, ByteString>\n\t\t\t\tfor (const key of Object.keys(init)) {\n\t\t\t\t\tconst value = init[key];\n\t\t\t\t\tthis.append(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new TypeError('Provided initializer must be an object');\n\t\t}\n\t}\n\n\t/**\n  * Return combined header value given name\n  *\n  * @param   String  name  Header name\n  * @return  Mixed\n  */\n\tget(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key === undefined) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this[MAP][key].join(', ');\n\t}\n\n\t/**\n  * Iterate over all headers\n  *\n  * @param   Function  callback  Executed for each item with parameters (value, name, thisArg)\n  * @param   Boolean   thisArg   `this` context for callback function\n  * @return  Void\n  */\n\tforEach(callback) {\n\t\tlet thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;\n\n\t\tlet pairs = getHeaders(this);\n\t\tlet i = 0;\n\t\twhile (i < pairs.length) {\n\t\t\tvar _pairs$i = pairs[i];\n\t\t\tconst name = _pairs$i[0],\n\t\t\t      value = _pairs$i[1];\n\n\t\t\tcallback.call(thisArg, value, name, this);\n\t\t\tpairs = getHeaders(this);\n\t\t\ti++;\n\t\t}\n\t}\n\n\t/**\n  * Overwrite header values given name\n  *\n  * @param   String  name   Header name\n  * @param   String  value  Header value\n  * @return  Void\n  */\n\tset(name, value) {\n\t\tname = `${name}`;\n\t\tvalue = `${value}`;\n\t\tvalidateName(name);\n\t\tvalidateValue(value);\n\t\tconst key = find(this[MAP], name);\n\t\tthis[MAP][key !== undefined ? key : name] = [value];\n\t}\n\n\t/**\n  * Append a value onto existing header\n  *\n  * @param   String  name   Header name\n  * @param   String  value  Header value\n  * @return  Void\n  */\n\tappend(name, value) {\n\t\tname = `${name}`;\n\t\tvalue = `${value}`;\n\t\tvalidateName(name);\n\t\tvalidateValue(value);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key !== undefined) {\n\t\t\tthis[MAP][key].push(value);\n\t\t} else {\n\t\t\tthis[MAP][name] = [value];\n\t\t}\n\t}\n\n\t/**\n  * Check for header name existence\n  *\n  * @param   String   name  Header name\n  * @return  Boolean\n  */\n\thas(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\treturn find(this[MAP], name) !== undefined;\n\t}\n\n\t/**\n  * Delete all header values given name\n  *\n  * @param   String  name  Header name\n  * @return  Void\n  */\n\tdelete(name) {\n\t\tname = `${name}`;\n\t\tvalidateName(name);\n\t\tconst key = find(this[MAP], name);\n\t\tif (key !== undefined) {\n\t\t\tdelete this[MAP][key];\n\t\t}\n\t}\n\n\t/**\n  * Return raw headers (non-spec api)\n  *\n  * @return  Object\n  */\n\traw() {\n\t\treturn this[MAP];\n\t}\n\n\t/**\n  * Get an iterator on keys.\n  *\n  * @return  Iterator\n  */\n\tkeys() {\n\t\treturn createHeadersIterator(this, 'key');\n\t}\n\n\t/**\n  * Get an iterator on values.\n  *\n  * @return  Iterator\n  */\n\tvalues() {\n\t\treturn createHeadersIterator(this, 'value');\n\t}\n\n\t/**\n  * Get an iterator on entries.\n  *\n  * This is the default iterator of the Headers object.\n  *\n  * @return  Iterator\n  */\n\t[Symbol.iterator]() {\n\t\treturn createHeadersIterator(this, 'key+value');\n\t}\n}\nHeaders.prototype.entries = Headers.prototype[Symbol.iterator];\n\nObject.defineProperty(Headers.prototype, Symbol.toStringTag, {\n\tvalue: 'Headers',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nObject.defineProperties(Headers.prototype, {\n\tget: { enumerable: true },\n\tforEach: { enumerable: true },\n\tset: { enumerable: true },\n\tappend: { enumerable: true },\n\thas: { enumerable: true },\n\tdelete: { enumerable: true },\n\tkeys: { enumerable: true },\n\tvalues: { enumerable: true },\n\tentries: { enumerable: true }\n});\n\nfunction getHeaders(headers) {\n\tlet kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value';\n\n\tconst keys = Object.keys(headers[MAP]).sort();\n\treturn keys.map(kind === 'key' ? function (k) {\n\t\treturn k.toLowerCase();\n\t} : kind === 'value' ? function (k) {\n\t\treturn headers[MAP][k].join(', ');\n\t} : function (k) {\n\t\treturn [k.toLowerCase(), headers[MAP][k].join(', ')];\n\t});\n}\n\nconst INTERNAL = Symbol('internal');\n\nfunction createHeadersIterator(target, kind) {\n\tconst iterator = Object.create(HeadersIteratorPrototype);\n\titerator[INTERNAL] = {\n\t\ttarget,\n\t\tkind,\n\t\tindex: 0\n\t};\n\treturn iterator;\n}\n\nconst HeadersIteratorPrototype = Object.setPrototypeOf({\n\tnext() {\n\t\t// istanbul ignore if\n\t\tif (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {\n\t\t\tthrow new TypeError('Value of `this` is not a HeadersIterator');\n\t\t}\n\n\t\tvar _INTERNAL = this[INTERNAL];\n\t\tconst target = _INTERNAL.target,\n\t\t      kind = _INTERNAL.kind,\n\t\t      index = _INTERNAL.index;\n\n\t\tconst values = getHeaders(target, kind);\n\t\tconst len = values.length;\n\t\tif (index >= len) {\n\t\t\treturn {\n\t\t\t\tvalue: undefined,\n\t\t\t\tdone: true\n\t\t\t};\n\t\t}\n\n\t\tthis[INTERNAL].index = index + 1;\n\n\t\treturn {\n\t\t\tvalue: values[index],\n\t\t\tdone: false\n\t\t};\n\t}\n}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));\n\nObject.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {\n\tvalue: 'HeadersIterator',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\n/**\n * Export the Headers object in a form that Node.js can consume.\n *\n * @param   Headers  headers\n * @return  Object\n */\nfunction exportNodeCompatibleHeaders(headers) {\n\tconst obj = Object.assign({ __proto__: null }, headers[MAP]);\n\n\t// http.request() only supports string as Host header. This hack makes\n\t// specifying custom Host header possible.\n\tconst hostHeaderKey = find(headers[MAP], 'Host');\n\tif (hostHeaderKey !== undefined) {\n\t\tobj[hostHeaderKey] = obj[hostHeaderKey][0];\n\t}\n\n\treturn obj;\n}\n\n/**\n * Create a Headers object from an object of headers, ignoring those that do\n * not conform to HTTP grammar productions.\n *\n * @param   Object  obj  Object of headers\n * @return  Headers\n */\nfunction createHeadersLenient(obj) {\n\tconst headers = new Headers();\n\tfor (const name of Object.keys(obj)) {\n\t\tif (invalidTokenRegex.test(name)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (Array.isArray(obj[name])) {\n\t\t\tfor (const val of obj[name]) {\n\t\t\t\tif (invalidHeaderCharRegex.test(val)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (headers[MAP][name] === undefined) {\n\t\t\t\t\theaders[MAP][name] = [val];\n\t\t\t\t} else {\n\t\t\t\t\theaders[MAP][name].push(val);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (!invalidHeaderCharRegex.test(obj[name])) {\n\t\t\theaders[MAP][name] = [obj[name]];\n\t\t}\n\t}\n\treturn headers;\n}\n\nconst INTERNALS$1 = Symbol('Response internals');\n\n// fix an issue where \"STATUS_CODES\" aren't a named export for node <10\nconst STATUS_CODES = http.STATUS_CODES;\n\n/**\n * Response class\n *\n * @param   Stream  body  Readable stream\n * @param   Object  opts  Response options\n * @return  Void\n */\nclass Response {\n\tconstructor() {\n\t\tlet body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n\t\tlet opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n\t\tBody.call(this, body, opts);\n\n\t\tconst status = opts.status || 200;\n\t\tconst headers = new Headers(opts.headers);\n\n\t\tif (body != null && !headers.has('Content-Type')) {\n\t\t\tconst contentType = extractContentType(body);\n\t\t\tif (contentType) {\n\t\t\t\theaders.append('Content-Type', contentType);\n\t\t\t}\n\t\t}\n\n\t\tthis[INTERNALS$1] = {\n\t\t\turl: opts.url,\n\t\t\tstatus,\n\t\t\tstatusText: opts.statusText || STATUS_CODES[status],\n\t\t\theaders,\n\t\t\tcounter: opts.counter\n\t\t};\n\t}\n\n\tget url() {\n\t\treturn this[INTERNALS$1].url || '';\n\t}\n\n\tget status() {\n\t\treturn this[INTERNALS$1].status;\n\t}\n\n\t/**\n  * Convenience property representing if the request ended normally\n  */\n\tget ok() {\n\t\treturn this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300;\n\t}\n\n\tget redirected() {\n\t\treturn this[INTERNALS$1].counter > 0;\n\t}\n\n\tget statusText() {\n\t\treturn this[INTERNALS$1].statusText;\n\t}\n\n\tget headers() {\n\t\treturn this[INTERNALS$1].headers;\n\t}\n\n\t/**\n  * Clone this response\n  *\n  * @return  Response\n  */\n\tclone() {\n\t\treturn new Response(clone(this), {\n\t\t\turl: this.url,\n\t\t\tstatus: this.status,\n\t\t\tstatusText: this.statusText,\n\t\t\theaders: this.headers,\n\t\t\tok: this.ok,\n\t\t\tredirected: this.redirected\n\t\t});\n\t}\n}\n\nBody.mixIn(Response.prototype);\n\nObject.defineProperties(Response.prototype, {\n\turl: { enumerable: true },\n\tstatus: { enumerable: true },\n\tok: { enumerable: true },\n\tredirected: { enumerable: true },\n\tstatusText: { enumerable: true },\n\theaders: { enumerable: true },\n\tclone: { enumerable: true }\n});\n\nObject.defineProperty(Response.prototype, Symbol.toStringTag, {\n\tvalue: 'Response',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nconst INTERNALS$2 = Symbol('Request internals');\nconst URL = Url.URL || whatwgUrl.URL;\n\n// fix an issue where \"format\", \"parse\" aren't a named export for node <10\nconst parse_url = Url.parse;\nconst format_url = Url.format;\n\n/**\n * Wrapper around `new URL` to handle arbitrary URLs\n *\n * @param  {string} urlStr\n * @return {void}\n */\nfunction parseURL(urlStr) {\n\t/*\n \tCheck whether the URL is absolute or not\n \t\tScheme: https://tools.ietf.org/html/rfc3986#section-3.1\n \tAbsolute URL: https://tools.ietf.org/html/rfc3986#section-4.3\n */\n\tif (/^[a-zA-Z][a-zA-Z\\d+\\-.]*:/.exec(urlStr)) {\n\t\turlStr = new URL(urlStr).toString();\n\t}\n\n\t// Fallback to old implementation for arbitrary URLs\n\treturn parse_url(urlStr);\n}\n\nconst streamDestructionSupported = 'destroy' in Stream.Readable.prototype;\n\n/**\n * Check if a value is an instance of Request.\n *\n * @param   Mixed   input\n * @return  Boolean\n */\nfunction isRequest(input) {\n\treturn typeof input === 'object' && typeof input[INTERNALS$2] === 'object';\n}\n\nfunction isAbortSignal(signal) {\n\tconst proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal);\n\treturn !!(proto && proto.constructor.name === 'AbortSignal');\n}\n\n/**\n * Request class\n *\n * @param   Mixed   input  Url or Request instance\n * @param   Object  init   Custom options\n * @return  Void\n */\nclass Request {\n\tconstructor(input) {\n\t\tlet init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n\t\tlet parsedURL;\n\n\t\t// normalize input\n\t\tif (!isRequest(input)) {\n\t\t\tif (input && input.href) {\n\t\t\t\t// in order to support Node.js' Url objects; though WHATWG's URL objects\n\t\t\t\t// will fall into this branch also (since their `toString()` will return\n\t\t\t\t// `href` property anyway)\n\t\t\t\tparsedURL = parseURL(input.href);\n\t\t\t} else {\n\t\t\t\t// coerce input to a string before attempting to parse\n\t\t\t\tparsedURL = parseURL(`${input}`);\n\t\t\t}\n\t\t\tinput = {};\n\t\t} else {\n\t\t\tparsedURL = parseURL(input.url);\n\t\t}\n\n\t\tlet method = init.method || input.method || 'GET';\n\t\tmethod = method.toUpperCase();\n\n\t\tif ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) {\n\t\t\tthrow new TypeError('Request with GET/HEAD method cannot have body');\n\t\t}\n\n\t\tlet inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null;\n\n\t\tBody.call(this, inputBody, {\n\t\t\ttimeout: init.timeout || input.timeout || 0,\n\t\t\tsize: init.size || input.size || 0\n\t\t});\n\n\t\tconst headers = new Headers(init.headers || input.headers || {});\n\n\t\tif (inputBody != null && !headers.has('Content-Type')) {\n\t\t\tconst contentType = extractContentType(inputBody);\n\t\t\tif (contentType) {\n\t\t\t\theaders.append('Content-Type', contentType);\n\t\t\t}\n\t\t}\n\n\t\tlet signal = isRequest(input) ? input.signal : null;\n\t\tif ('signal' in init) signal = init.signal;\n\n\t\tif (signal != null && !isAbortSignal(signal)) {\n\t\t\tthrow new TypeError('Expected signal to be an instanceof AbortSignal');\n\t\t}\n\n\t\tthis[INTERNALS$2] = {\n\t\t\tmethod,\n\t\t\tredirect: init.redirect || input.redirect || 'follow',\n\t\t\theaders,\n\t\t\tparsedURL,\n\t\t\tsignal\n\t\t};\n\n\t\t// node-fetch-only options\n\t\tthis.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;\n\t\tthis.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;\n\t\tthis.counter = init.counter || input.counter || 0;\n\t\tthis.agent = init.agent || input.agent;\n\t}\n\n\tget method() {\n\t\treturn this[INTERNALS$2].method;\n\t}\n\n\tget url() {\n\t\treturn format_url(this[INTERNALS$2].parsedURL);\n\t}\n\n\tget headers() {\n\t\treturn this[INTERNALS$2].headers;\n\t}\n\n\tget redirect() {\n\t\treturn this[INTERNALS$2].redirect;\n\t}\n\n\tget signal() {\n\t\treturn this[INTERNALS$2].signal;\n\t}\n\n\t/**\n  * Clone this request\n  *\n  * @return  Request\n  */\n\tclone() {\n\t\treturn new Request(this);\n\t}\n}\n\nBody.mixIn(Request.prototype);\n\nObject.defineProperty(Request.prototype, Symbol.toStringTag, {\n\tvalue: 'Request',\n\twritable: false,\n\tenumerable: false,\n\tconfigurable: true\n});\n\nObject.defineProperties(Request.prototype, {\n\tmethod: { enumerable: true },\n\turl: { enumerable: true },\n\theaders: { enumerable: true },\n\tredirect: { enumerable: true },\n\tclone: { enumerable: true },\n\tsignal: { enumerable: true }\n});\n\n/**\n * Convert a Request to Node.js http request options.\n *\n * @param   Request  A Request instance\n * @return  Object   The options object to be passed to http.request\n */\nfunction getNodeRequestOptions(request) {\n\tconst parsedURL = request[INTERNALS$2].parsedURL;\n\tconst headers = new Headers(request[INTERNALS$2].headers);\n\n\t// fetch step 1.3\n\tif (!headers.has('Accept')) {\n\t\theaders.set('Accept', '*/*');\n\t}\n\n\t// Basic fetch\n\tif (!parsedURL.protocol || !parsedURL.hostname) {\n\t\tthrow new TypeError('Only absolute URLs are supported');\n\t}\n\n\tif (!/^https?:$/.test(parsedURL.protocol)) {\n\t\tthrow new TypeError('Only HTTP(S) protocols are supported');\n\t}\n\n\tif (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) {\n\t\tthrow new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8');\n\t}\n\n\t// HTTP-network-or-cache fetch steps 2.4-2.7\n\tlet contentLengthValue = null;\n\tif (request.body == null && /^(POST|PUT)$/i.test(request.method)) {\n\t\tcontentLengthValue = '0';\n\t}\n\tif (request.body != null) {\n\t\tconst totalBytes = getTotalBytes(request);\n\t\tif (typeof totalBytes === 'number') {\n\t\t\tcontentLengthValue = String(totalBytes);\n\t\t}\n\t}\n\tif (contentLengthValue) {\n\t\theaders.set('Content-Length', contentLengthValue);\n\t}\n\n\t// HTTP-network-or-cache fetch step 2.11\n\tif (!headers.has('User-Agent')) {\n\t\theaders.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');\n\t}\n\n\t// HTTP-network-or-cache fetch step 2.15\n\tif (request.compress && !headers.has('Accept-Encoding')) {\n\t\theaders.set('Accept-Encoding', 'gzip,deflate');\n\t}\n\n\tlet agent = request.agent;\n\tif (typeof agent === 'function') {\n\t\tagent = agent(parsedURL);\n\t}\n\n\tif (!headers.has('Connection') && !agent) {\n\t\theaders.set('Connection', 'close');\n\t}\n\n\t// HTTP-network fetch step 4.2\n\t// chunked encoding is handled by Node.js\n\n\treturn Object.assign({}, parsedURL, {\n\t\tmethod: request.method,\n\t\theaders: exportNodeCompatibleHeaders(headers),\n\t\tagent\n\t});\n}\n\n/**\n * abort-error.js\n *\n * AbortError interface for cancelled requests\n */\n\n/**\n * Create AbortError instance\n *\n * @param   String      message      Error message for human\n * @return  AbortError\n */\nfunction AbortError(message) {\n  Error.call(this, message);\n\n  this.type = 'aborted';\n  this.message = message;\n\n  // hide custom error implementation details from end-users\n  Error.captureStackTrace(this, this.constructor);\n}\n\nAbortError.prototype = Object.create(Error.prototype);\nAbortError.prototype.constructor = AbortError;\nAbortError.prototype.name = 'AbortError';\n\n// fix an issue where \"PassThrough\", \"resolve\" aren't a named export for node <10\nconst PassThrough$1 = Stream.PassThrough;\nconst resolve_url = Url.resolve;\n\n/**\n * Fetch function\n *\n * @param   Mixed    url   Absolute url or Request instance\n * @param   Object   opts  Fetch options\n * @return  Promise\n */\nfunction fetch(url, opts) {\n\n\t// allow custom promise\n\tif (!fetch.Promise) {\n\t\tthrow new Error('native promise missing, set fetch.Promise to your favorite alternative');\n\t}\n\n\tBody.Promise = fetch.Promise;\n\n\t// wrap http.request into fetch\n\treturn new fetch.Promise(function (resolve, reject) {\n\t\t// build request object\n\t\tconst request = new Request(url, opts);\n\t\tconst options = getNodeRequestOptions(request);\n\n\t\tconst send = (options.protocol === 'https:' ? https : http).request;\n\t\tconst signal = request.signal;\n\n\t\tlet response = null;\n\n\t\tconst abort = function abort() {\n\t\t\tlet error = new AbortError('The user aborted a request.');\n\t\t\treject(error);\n\t\t\tif (request.body && request.body instanceof Stream.Readable) {\n\t\t\t\trequest.body.destroy(error);\n\t\t\t}\n\t\t\tif (!response || !response.body) return;\n\t\t\tresponse.body.emit('error', error);\n\t\t};\n\n\t\tif (signal && signal.aborted) {\n\t\t\tabort();\n\t\t\treturn;\n\t\t}\n\n\t\tconst abortAndFinalize = function abortAndFinalize() {\n\t\t\tabort();\n\t\t\tfinalize();\n\t\t};\n\n\t\t// send request\n\t\tconst req = send(options);\n\t\tlet reqTimeout;\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', abortAndFinalize);\n\t\t}\n\n\t\tfunction finalize() {\n\t\t\treq.abort();\n\t\t\tif (signal) signal.removeEventListener('abort', abortAndFinalize);\n\t\t\tclearTimeout(reqTimeout);\n\t\t}\n\n\t\tif (request.timeout) {\n\t\t\treq.once('socket', function (socket) {\n\t\t\t\treqTimeout = setTimeout(function () {\n\t\t\t\t\treject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));\n\t\t\t\t\tfinalize();\n\t\t\t\t}, request.timeout);\n\t\t\t});\n\t\t}\n\n\t\treq.on('error', function (err) {\n\t\t\treject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));\n\t\t\tfinalize();\n\t\t});\n\n\t\treq.on('response', function (res) {\n\t\t\tclearTimeout(reqTimeout);\n\n\t\t\tconst headers = createHeadersLenient(res.headers);\n\n\t\t\t// HTTP fetch step 5\n\t\t\tif (fetch.isRedirect(res.statusCode)) {\n\t\t\t\t// HTTP fetch step 5.2\n\t\t\t\tconst location = headers.get('Location');\n\n\t\t\t\t// HTTP fetch step 5.3\n\t\t\t\tconst locationURL = location === null ? null : resolve_url(request.url, location);\n\n\t\t\t\t// HTTP fetch step 5.5\n\t\t\t\tswitch (request.redirect) {\n\t\t\t\t\tcase 'error':\n\t\t\t\t\t\treject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t\tcase 'manual':\n\t\t\t\t\t\t// node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.\n\t\t\t\t\t\tif (locationURL !== null) {\n\t\t\t\t\t\t\t// handle corrupted header\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\theaders.set('Location', locationURL);\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t// istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request\n\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'follow':\n\t\t\t\t\t\t// HTTP-redirect fetch step 2\n\t\t\t\t\t\tif (locationURL === null) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 5\n\t\t\t\t\t\tif (request.counter >= request.follow) {\n\t\t\t\t\t\t\treject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));\n\t\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 6 (counter increment)\n\t\t\t\t\t\t// Create a new Request object.\n\t\t\t\t\t\tconst requestOpts = {\n\t\t\t\t\t\t\theaders: new Headers(request.headers),\n\t\t\t\t\t\t\tfollow: request.follow,\n\t\t\t\t\t\t\tcounter: request.counter + 1,\n\t\t\t\t\t\t\tagent: request.agent,\n\t\t\t\t\t\t\tcompress: request.compress,\n\t\t\t\t\t\t\tmethod: request.method,\n\t\t\t\t\t\t\tbody: request.body,\n\t\t\t\t\t\t\tsignal: request.signal,\n\t\t\t\t\t\t\ttimeout: request.timeout,\n\t\t\t\t\t\t\tsize: request.size\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 9\n\t\t\t\t\t\tif (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {\n\t\t\t\t\t\t\treject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));\n\t\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 11\n\t\t\t\t\t\tif (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {\n\t\t\t\t\t\t\trequestOpts.method = 'GET';\n\t\t\t\t\t\t\trequestOpts.body = undefined;\n\t\t\t\t\t\t\trequestOpts.headers.delete('content-length');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// HTTP-redirect fetch step 15\n\t\t\t\t\t\tresolve(fetch(new Request(locationURL, requestOpts)));\n\t\t\t\t\t\tfinalize();\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// prepare response\n\t\t\tres.once('end', function () {\n\t\t\t\tif (signal) signal.removeEventListener('abort', abortAndFinalize);\n\t\t\t});\n\t\t\tlet body = res.pipe(new PassThrough$1());\n\n\t\t\tconst response_options = {\n\t\t\t\turl: request.url,\n\t\t\t\tstatus: res.statusCode,\n\t\t\t\tstatusText: res.statusMessage,\n\t\t\t\theaders: headers,\n\t\t\t\tsize: request.size,\n\t\t\t\ttimeout: request.timeout,\n\t\t\t\tcounter: request.counter\n\t\t\t};\n\n\t\t\t// HTTP-network fetch step 12.1.1.3\n\t\t\tconst codings = headers.get('Content-Encoding');\n\n\t\t\t// HTTP-network fetch step 12.1.1.4: handle content codings\n\n\t\t\t// in following scenarios we ignore compression support\n\t\t\t// 1. compression support is disabled\n\t\t\t// 2. HEAD request\n\t\t\t// 3. no Content-Encoding header\n\t\t\t// 4. no content response (204)\n\t\t\t// 5. content not modified response (304)\n\t\t\tif (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// For Node v6+\n\t\t\t// Be less strict when decoding compressed responses, since sometimes\n\t\t\t// servers send slightly invalid responses that are still accepted\n\t\t\t// by common browsers.\n\t\t\t// Always using Z_SYNC_FLUSH is what cURL does.\n\t\t\tconst zlibOptions = {\n\t\t\t\tflush: zlib.Z_SYNC_FLUSH,\n\t\t\t\tfinishFlush: zlib.Z_SYNC_FLUSH\n\t\t\t};\n\n\t\t\t// for gzip\n\t\t\tif (codings == 'gzip' || codings == 'x-gzip') {\n\t\t\t\tbody = body.pipe(zlib.createGunzip(zlibOptions));\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// for deflate\n\t\t\tif (codings == 'deflate' || codings == 'x-deflate') {\n\t\t\t\t// handle the infamous raw deflate response from old servers\n\t\t\t\t// a hack for old IIS and Apache servers\n\t\t\t\tconst raw = res.pipe(new PassThrough$1());\n\t\t\t\traw.once('data', function (chunk) {\n\t\t\t\t\t// see http://stackoverflow.com/questions/37519828\n\t\t\t\t\tif ((chunk[0] & 0x0F) === 0x08) {\n\t\t\t\t\t\tbody = body.pipe(zlib.createInflate());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbody = body.pipe(zlib.createInflateRaw());\n\t\t\t\t\t}\n\t\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\t\tresolve(response);\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// for br\n\t\t\tif (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') {\n\t\t\t\tbody = body.pipe(zlib.createBrotliDecompress());\n\t\t\t\tresponse = new Response(body, response_options);\n\t\t\t\tresolve(response);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// otherwise, use response as-is\n\t\t\tresponse = new Response(body, response_options);\n\t\t\tresolve(response);\n\t\t});\n\n\t\twriteToStream(req, request);\n\t});\n}\n/**\n * Redirect code matching\n *\n * @param   Number   code  Status code\n * @return  Boolean\n */\nfetch.isRedirect = function (code) {\n\treturn code === 301 || code === 302 || code === 303 || code === 307 || code === 308;\n};\n\n// expose Promise\nfetch.Promise = global.Promise;\n\nmodule.exports = exports = fetch;\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.default = exports;\nexports.Headers = Headers;\nexports.Request = Request;\nexports.Response = Response;\nexports.FetchError = FetchError;\n\n\n/***/ }),\n\n/***/ 1223:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nvar wrappy = __webpack_require__(2940)\nmodule.exports = wrappy(once)\nmodule.exports.strict = wrappy(onceStrict)\n\nonce.proto = once(function () {\n  Object.defineProperty(Function.prototype, 'once', {\n    value: function () {\n      return once(this)\n    },\n    configurable: true\n  })\n\n  Object.defineProperty(Function.prototype, 'onceStrict', {\n    value: function () {\n      return onceStrict(this)\n    },\n    configurable: true\n  })\n})\n\nfunction once (fn) {\n  var f = function () {\n    if (f.called) return f.value\n    f.called = true\n    return f.value = fn.apply(this, arguments)\n  }\n  f.called = false\n  return f\n}\n\nfunction onceStrict (fn) {\n  var f = function () {\n    if (f.called)\n      throw new Error(f.onceError)\n    f.called = true\n    return f.value = fn.apply(this, arguments)\n  }\n  var name = fn.name || 'Function wrapped with `once`'\n  f.onceError = name + \" shouldn't be called more than once\"\n  f.called = false\n  return f\n}\n\n\n/***/ }),\n\n/***/ 4256:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nvar punycode = __webpack_require__(4213);\nvar mappingTable = __webpack_require__(68);\n\nvar PROCESSING_OPTIONS = {\n  TRANSITIONAL: 0,\n  NONTRANSITIONAL: 1\n};\n\nfunction normalize(str) { // fix bug in v8\n  return str.split('\\u0000').map(function (s) { return s.normalize('NFC'); }).join('\\u0000');\n}\n\nfunction findStatus(val) {\n  var start = 0;\n  var end = mappingTable.length - 1;\n\n  while (start <= end) {\n    var mid = Math.floor((start + end) / 2);\n\n    var target = mappingTable[mid];\n    if (target[0][0] <= val && target[0][1] >= val) {\n      return target;\n    } else if (target[0][0] > val) {\n      end = mid - 1;\n    } else {\n      start = mid + 1;\n    }\n  }\n\n  return null;\n}\n\nvar regexAstralSymbols = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g;\n\nfunction countSymbols(string) {\n  return string\n    // replace every surrogate pair with a BMP symbol\n    .replace(regexAstralSymbols, '_')\n    // then get the length\n    .length;\n}\n\nfunction mapChars(domain_name, useSTD3, processing_option) {\n  var hasError = false;\n  var processed = \"\";\n\n  var len = countSymbols(domain_name);\n  for (var i = 0; i < len; ++i) {\n    var codePoint = domain_name.codePointAt(i);\n    var status = findStatus(codePoint);\n\n    switch (status[1]) {\n      case \"disallowed\":\n        hasError = true;\n        processed += String.fromCodePoint(codePoint);\n        break;\n      case \"ignored\":\n        break;\n      case \"mapped\":\n        processed += String.fromCodePoint.apply(String, status[2]);\n        break;\n      case \"deviation\":\n        if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) {\n          processed += String.fromCodePoint.apply(String, status[2]);\n        } else {\n          processed += String.fromCodePoint(codePoint);\n        }\n        break;\n      case \"valid\":\n        processed += String.fromCodePoint(codePoint);\n        break;\n      case \"disallowed_STD3_mapped\":\n        if (useSTD3) {\n          hasError = true;\n          processed += String.fromCodePoint(codePoint);\n        } else {\n          processed += String.fromCodePoint.apply(String, status[2]);\n        }\n        break;\n      case \"disallowed_STD3_valid\":\n        if (useSTD3) {\n          hasError = true;\n        }\n\n        processed += String.fromCodePoint(codePoint);\n        break;\n    }\n  }\n\n  return {\n    string: processed,\n    error: hasError\n  };\n}\n\nvar combiningMarksRegex = /[\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u08E4-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A01-\\u0A03\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AE2\\u0AE3\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C00-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81-\\u0C83\\u0CBC\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D01-\\u0D03\\u0D3E-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D82\\u0D83\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102B-\\u103E\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F\\u109A-\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B4-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u192B\\u1930-\\u193B\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A17-\\u1A1B\\u1A55-\\u1A5E\\u1A60-\\u1A7C\\u1A7F\\u1AB0-\\u1ABE\\u1B00-\\u1B04\\u1B34-\\u1B44\\u1B6B-\\u1B73\\u1B80-\\u1B82\\u1BA1-\\u1BAD\\u1BE6-\\u1BF3\\u1C24-\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE8\\u1CED\\u1CF2-\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DF5\\u1DFC-\\u1DFF\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA823-\\uA827\\uA880\\uA881\\uA8B4-\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA953\\uA980-\\uA983\\uA9B3-\\uA9C0\\uA9E5\\uAA29-\\uAA36\\uAA43\\uAA4C\\uAA4D\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEB-\\uAAEF\\uAAF5\\uAAF6\\uABE3-\\uABEA\\uABEC\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2D]|\\uD800[\\uDDFD\\uDEE0\\uDF76-\\uDF7A]|\\uD802[\\uDE01-\\uDE03\\uDE05\\uDE06\\uDE0C-\\uDE0F\\uDE38-\\uDE3A\\uDE3F\\uDEE5\\uDEE6]|\\uD804[\\uDC00-\\uDC02\\uDC38-\\uDC46\\uDC7F-\\uDC82\\uDCB0-\\uDCBA\\uDD00-\\uDD02\\uDD27-\\uDD34\\uDD73\\uDD80-\\uDD82\\uDDB3-\\uDDC0\\uDE2C-\\uDE37\\uDEDF-\\uDEEA\\uDF01-\\uDF03\\uDF3C\\uDF3E-\\uDF44\\uDF47\\uDF48\\uDF4B-\\uDF4D\\uDF57\\uDF62\\uDF63\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDCB0-\\uDCC3\\uDDAF-\\uDDB5\\uDDB8-\\uDDC0\\uDE30-\\uDE40\\uDEAB-\\uDEB7]|\\uD81A[\\uDEF0-\\uDEF4\\uDF30-\\uDF36]|\\uD81B[\\uDF51-\\uDF7E\\uDF8F-\\uDF92]|\\uD82F[\\uDC9D\\uDC9E]|\\uD834[\\uDD65-\\uDD69\\uDD6D-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD83A[\\uDCD0-\\uDCD6]|\\uDB40[\\uDD00-\\uDDEF]/;\n\nfunction validateLabel(label, processing_option) {\n  if (label.substr(0, 4) === \"xn--\") {\n    label = punycode.toUnicode(label);\n    processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL;\n  }\n\n  var error = false;\n\n  if (normalize(label) !== label ||\n      (label[3] === \"-\" && label[4] === \"-\") ||\n      label[0] === \"-\" || label[label.length - 1] === \"-\" ||\n      label.indexOf(\".\") !== -1 ||\n      label.search(combiningMarksRegex) === 0) {\n    error = true;\n  }\n\n  var len = countSymbols(label);\n  for (var i = 0; i < len; ++i) {\n    var status = findStatus(label.codePointAt(i));\n    if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== \"valid\") ||\n        (processing === PROCESSING_OPTIONS.NONTRANSITIONAL &&\n         status[1] !== \"valid\" && status[1] !== \"deviation\")) {\n      error = true;\n      break;\n    }\n  }\n\n  return {\n    label: label,\n    error: error\n  };\n}\n\nfunction processing(domain_name, useSTD3, processing_option) {\n  var result = mapChars(domain_name, useSTD3, processing_option);\n  result.string = normalize(result.string);\n\n  var labels = result.string.split(\".\");\n  for (var i = 0; i < labels.length; ++i) {\n    try {\n      var validation = validateLabel(labels[i]);\n      labels[i] = validation.label;\n      result.error = result.error || validation.error;\n    } catch(e) {\n      result.error = true;\n    }\n  }\n\n  return {\n    string: labels.join(\".\"),\n    error: result.error\n  };\n}\n\nmodule.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) {\n  var result = processing(domain_name, useSTD3, processing_option);\n  var labels = result.string.split(\".\");\n  labels = labels.map(function(l) {\n    try {\n      return punycode.toASCII(l);\n    } catch(e) {\n      result.error = true;\n      return l;\n    }\n  });\n\n  if (verifyDnsLength) {\n    var total = labels.slice(0, labels.length - 1).join(\".\").length;\n    if (total.length > 253 || total.length === 0) {\n      result.error = true;\n    }\n\n    for (var i=0; i < labels.length; ++i) {\n      if (labels.length > 63 || labels.length === 0) {\n        result.error = true;\n        break;\n      }\n    }\n  }\n\n  if (result.error) return null;\n  return labels.join(\".\");\n};\n\nmodule.exports.toUnicode = function(domain_name, useSTD3) {\n  var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL);\n\n  return {\n    domain: result.string,\n    error: result.error\n  };\n};\n\nmodule.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS;\n\n\n/***/ }),\n\n/***/ 4294:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nmodule.exports = __webpack_require__(4219);\n\n\n/***/ }),\n\n/***/ 4219:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nvar net = __webpack_require__(1631);\nvar tls = __webpack_require__(4016);\nvar http = __webpack_require__(8605);\nvar https = __webpack_require__(7211);\nvar events = __webpack_require__(8614);\nvar assert = __webpack_require__(2357);\nvar util = __webpack_require__(1669);\n\n\nexports.httpOverHttp = httpOverHttp;\nexports.httpsOverHttp = httpsOverHttp;\nexports.httpOverHttps = httpOverHttps;\nexports.httpsOverHttps = httpsOverHttps;\n\n\nfunction httpOverHttp(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = http.request;\n  return agent;\n}\n\nfunction httpsOverHttp(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = http.request;\n  agent.createSocket = createSecureSocket;\n  agent.defaultPort = 443;\n  return agent;\n}\n\nfunction httpOverHttps(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = https.request;\n  return agent;\n}\n\nfunction httpsOverHttps(options) {\n  var agent = new TunnelingAgent(options);\n  agent.request = https.request;\n  agent.createSocket = createSecureSocket;\n  agent.defaultPort = 443;\n  return agent;\n}\n\n\nfunction TunnelingAgent(options) {\n  var self = this;\n  self.options = options || {};\n  self.proxyOptions = self.options.proxy || {};\n  self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;\n  self.requests = [];\n  self.sockets = [];\n\n  self.on('free', function onFree(socket, host, port, localAddress) {\n    var options = toOptions(host, port, localAddress);\n    for (var i = 0, len = self.requests.length; i < len; ++i) {\n      var pending = self.requests[i];\n      if (pending.host === options.host && pending.port === options.port) {\n        // Detect the request to connect same origin server,\n        // reuse the connection.\n        self.requests.splice(i, 1);\n        pending.request.onSocket(socket);\n        return;\n      }\n    }\n    socket.destroy();\n    self.removeSocket(socket);\n  });\n}\nutil.inherits(TunnelingAgent, events.EventEmitter);\n\nTunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {\n  var self = this;\n  var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));\n\n  if (self.sockets.length >= this.maxSockets) {\n    // We are over limit so we'll add it to the queue.\n    self.requests.push(options);\n    return;\n  }\n\n  // If we are under maxSockets create a new one.\n  self.createSocket(options, function(socket) {\n    socket.on('free', onFree);\n    socket.on('close', onCloseOrRemove);\n    socket.on('agentRemove', onCloseOrRemove);\n    req.onSocket(socket);\n\n    function onFree() {\n      self.emit('free', socket, options);\n    }\n\n    function onCloseOrRemove(err) {\n      self.removeSocket(socket);\n      socket.removeListener('free', onFree);\n      socket.removeListener('close', onCloseOrRemove);\n      socket.removeListener('agentRemove', onCloseOrRemove);\n    }\n  });\n};\n\nTunnelingAgent.prototype.createSocket = function createSocket(options, cb) {\n  var self = this;\n  var placeholder = {};\n  self.sockets.push(placeholder);\n\n  var connectOptions = mergeOptions({}, self.proxyOptions, {\n    method: 'CONNECT',\n    path: options.host + ':' + options.port,\n    agent: false,\n    headers: {\n      host: options.host + ':' + options.port\n    }\n  });\n  if (options.localAddress) {\n    connectOptions.localAddress = options.localAddress;\n  }\n  if (connectOptions.proxyAuth) {\n    connectOptions.headers = connectOptions.headers || {};\n    connectOptions.headers['Proxy-Authorization'] = 'Basic ' +\n        new Buffer(connectOptions.proxyAuth).toString('base64');\n  }\n\n  debug('making CONNECT request');\n  var connectReq = self.request(connectOptions);\n  connectReq.useChunkedEncodingByDefault = false; // for v0.6\n  connectReq.once('response', onResponse); // for v0.6\n  connectReq.once('upgrade', onUpgrade);   // for v0.6\n  connectReq.once('connect', onConnect);   // for v0.7 or later\n  connectReq.once('error', onError);\n  connectReq.end();\n\n  function onResponse(res) {\n    // Very hacky. This is necessary to avoid http-parser leaks.\n    res.upgrade = true;\n  }\n\n  function onUpgrade(res, socket, head) {\n    // Hacky.\n    process.nextTick(function() {\n      onConnect(res, socket, head);\n    });\n  }\n\n  function onConnect(res, socket, head) {\n    connectReq.removeAllListeners();\n    socket.removeAllListeners();\n\n    if (res.statusCode !== 200) {\n      debug('tunneling socket could not be established, statusCode=%d',\n        res.statusCode);\n      socket.destroy();\n      var error = new Error('tunneling socket could not be established, ' +\n        'statusCode=' + res.statusCode);\n      error.code = 'ECONNRESET';\n      options.request.emit('error', error);\n      self.removeSocket(placeholder);\n      return;\n    }\n    if (head.length > 0) {\n      debug('got illegal response body from proxy');\n      socket.destroy();\n      var error = new Error('got illegal response body from proxy');\n      error.code = 'ECONNRESET';\n      options.request.emit('error', error);\n      self.removeSocket(placeholder);\n      return;\n    }\n    debug('tunneling connection has established');\n    self.sockets[self.sockets.indexOf(placeholder)] = socket;\n    return cb(socket);\n  }\n\n  function onError(cause) {\n    connectReq.removeAllListeners();\n\n    debug('tunneling socket could not be established, cause=%s\\n',\n          cause.message, cause.stack);\n    var error = new Error('tunneling socket could not be established, ' +\n                          'cause=' + cause.message);\n    error.code = 'ECONNRESET';\n    options.request.emit('error', error);\n    self.removeSocket(placeholder);\n  }\n};\n\nTunnelingAgent.prototype.removeSocket = function removeSocket(socket) {\n  var pos = this.sockets.indexOf(socket)\n  if (pos === -1) {\n    return;\n  }\n  this.sockets.splice(pos, 1);\n\n  var pending = this.requests.shift();\n  if (pending) {\n    // If we have pending requests and a socket gets closed a new one\n    // needs to be created to take over in the pool for the one that closed.\n    this.createSocket(pending, function(socket) {\n      pending.request.onSocket(socket);\n    });\n  }\n};\n\nfunction createSecureSocket(options, cb) {\n  var self = this;\n  TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {\n    var hostHeader = options.request.getHeader('host');\n    var tlsOptions = mergeOptions({}, self.options, {\n      socket: socket,\n      servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host\n    });\n\n    // 0 is dummy port for v0.6\n    var secureSocket = tls.connect(0, tlsOptions);\n    self.sockets[self.sockets.indexOf(socket)] = secureSocket;\n    cb(secureSocket);\n  });\n}\n\n\nfunction toOptions(host, port, localAddress) {\n  if (typeof host === 'string') { // since v0.10\n    return {\n      host: host,\n      port: port,\n      localAddress: localAddress\n    };\n  }\n  return host; // for v0.11 or later\n}\n\nfunction mergeOptions(target) {\n  for (var i = 1, len = arguments.length; i < len; ++i) {\n    var overrides = arguments[i];\n    if (typeof overrides === 'object') {\n      var keys = Object.keys(overrides);\n      for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {\n        var k = keys[j];\n        if (overrides[k] !== undefined) {\n          target[k] = overrides[k];\n        }\n      }\n    }\n  }\n  return target;\n}\n\n\nvar debug;\nif (process.env.NODE_DEBUG && /\\btunnel\\b/.test(process.env.NODE_DEBUG)) {\n  debug = function() {\n    var args = Array.prototype.slice.call(arguments);\n    if (typeof args[0] === 'string') {\n      args[0] = 'TUNNEL: ' + args[0];\n    } else {\n      args.unshift('TUNNEL:');\n    }\n    console.error.apply(console, args);\n  }\n} else {\n  debug = function() {};\n}\nexports.debug = debug; // for test\n\n\n/***/ }),\n\n/***/ 5030:\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\n\nfunction getUserAgent() {\n  if (typeof navigator === \"object\" && \"userAgent\" in navigator) {\n    return navigator.userAgent;\n  }\n\n  if (typeof process === \"object\" && \"version\" in process) {\n    return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`;\n  }\n\n  return \"<environment undetectable>\";\n}\n\nexports.getUserAgent = getUserAgent;\n//# sourceMappingURL=index.js.map\n\n\n/***/ }),\n\n/***/ 4886:\n/***/ ((module) => {\n\n\"use strict\";\n\n\nvar conversions = {};\nmodule.exports = conversions;\n\nfunction sign(x) {\n    return x < 0 ? -1 : 1;\n}\n\nfunction evenRound(x) {\n    // Round x to the nearest integer, choosing the even integer if it lies halfway between two.\n    if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor)\n        return Math.floor(x);\n    } else {\n        return Math.round(x);\n    }\n}\n\nfunction createNumberConversion(bitLength, typeOpts) {\n    if (!typeOpts.unsigned) {\n        --bitLength;\n    }\n    const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength);\n    const upperBound = Math.pow(2, bitLength) - 1;\n\n    const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength);\n    const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1);\n\n    return function(V, opts) {\n        if (!opts) opts = {};\n\n        let x = +V;\n\n        if (opts.enforceRange) {\n            if (!Number.isFinite(x)) {\n                throw new TypeError(\"Argument is not a finite number\");\n            }\n\n            x = sign(x) * Math.floor(Math.abs(x));\n            if (x < lowerBound || x > upperBound) {\n                throw new TypeError(\"Argument is not in byte range\");\n            }\n\n            return x;\n        }\n\n        if (!isNaN(x) && opts.clamp) {\n            x = evenRound(x);\n\n            if (x < lowerBound) x = lowerBound;\n            if (x > upperBound) x = upperBound;\n            return x;\n        }\n\n        if (!Number.isFinite(x) || x === 0) {\n            return 0;\n        }\n\n        x = sign(x) * Math.floor(Math.abs(x));\n        x = x % moduloVal;\n\n        if (!typeOpts.unsigned && x >= moduloBound) {\n            return x - moduloVal;\n        } else if (typeOpts.unsigned) {\n            if (x < 0) {\n              x += moduloVal;\n            } else if (x === -0) { // don't return negative zero\n              return 0;\n            }\n        }\n\n        return x;\n    }\n}\n\nconversions[\"void\"] = function () {\n    return undefined;\n};\n\nconversions[\"boolean\"] = function (val) {\n    return !!val;\n};\n\nconversions[\"byte\"] = createNumberConversion(8, { unsigned: false });\nconversions[\"octet\"] = createNumberConversion(8, { unsigned: true });\n\nconversions[\"short\"] = createNumberConversion(16, { unsigned: false });\nconversions[\"unsigned short\"] = createNumberConversion(16, { unsigned: true });\n\nconversions[\"long\"] = createNumberConversion(32, { unsigned: false });\nconversions[\"unsigned long\"] = createNumberConversion(32, { unsigned: true });\n\nconversions[\"long long\"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 });\nconversions[\"unsigned long long\"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 });\n\nconversions[\"double\"] = function (V) {\n    const x = +V;\n\n    if (!Number.isFinite(x)) {\n        throw new TypeError(\"Argument is not a finite floating-point value\");\n    }\n\n    return x;\n};\n\nconversions[\"unrestricted double\"] = function (V) {\n    const x = +V;\n\n    if (isNaN(x)) {\n        throw new TypeError(\"Argument is NaN\");\n    }\n\n    return x;\n};\n\n// not quite valid, but good enough for JS\nconversions[\"float\"] = conversions[\"double\"];\nconversions[\"unrestricted float\"] = conversions[\"unrestricted double\"];\n\nconversions[\"DOMString\"] = function (V, opts) {\n    if (!opts) opts = {};\n\n    if (opts.treatNullAsEmptyString && V === null) {\n        return \"\";\n    }\n\n    return String(V);\n};\n\nconversions[\"ByteString\"] = function (V, opts) {\n    const x = String(V);\n    let c = undefined;\n    for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) {\n        if (c > 255) {\n            throw new TypeError(\"Argument is not a valid bytestring\");\n        }\n    }\n\n    return x;\n};\n\nconversions[\"USVString\"] = function (V) {\n    const S = String(V);\n    const n = S.length;\n    const U = [];\n    for (let i = 0; i < n; ++i) {\n        const c = S.charCodeAt(i);\n        if (c < 0xD800 || c > 0xDFFF) {\n            U.push(String.fromCodePoint(c));\n        } else if (0xDC00 <= c && c <= 0xDFFF) {\n            U.push(String.fromCodePoint(0xFFFD));\n        } else {\n            if (i === n - 1) {\n                U.push(String.fromCodePoint(0xFFFD));\n            } else {\n                const d = S.charCodeAt(i + 1);\n                if (0xDC00 <= d && d <= 0xDFFF) {\n                    const a = c & 0x3FF;\n                    const b = d & 0x3FF;\n                    U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b));\n                    ++i;\n                } else {\n                    U.push(String.fromCodePoint(0xFFFD));\n                }\n            }\n        }\n    }\n\n    return U.join('');\n};\n\nconversions[\"Date\"] = function (V, opts) {\n    if (!(V instanceof Date)) {\n        throw new TypeError(\"Argument is not a Date object\");\n    }\n    if (isNaN(V)) {\n        return undefined;\n    }\n\n    return V;\n};\n\nconversions[\"RegExp\"] = function (V, opts) {\n    if (!(V instanceof RegExp)) {\n        V = new RegExp(V);\n    }\n\n    return V;\n};\n\n\n/***/ }),\n\n/***/ 7537:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\nconst usm = __webpack_require__(2158);\n\nexports.implementation = class URLImpl {\n  constructor(constructorArgs) {\n    const url = constructorArgs[0];\n    const base = constructorArgs[1];\n\n    let parsedBase = null;\n    if (base !== undefined) {\n      parsedBase = usm.basicURLParse(base);\n      if (parsedBase === \"failure\") {\n        throw new TypeError(\"Invalid base URL\");\n      }\n    }\n\n    const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase });\n    if (parsedURL === \"failure\") {\n      throw new TypeError(\"Invalid URL\");\n    }\n\n    this._url = parsedURL;\n\n    // TODO: query stuff\n  }\n\n  get href() {\n    return usm.serializeURL(this._url);\n  }\n\n  set href(v) {\n    const parsedURL = usm.basicURLParse(v);\n    if (parsedURL === \"failure\") {\n      throw new TypeError(\"Invalid URL\");\n    }\n\n    this._url = parsedURL;\n  }\n\n  get origin() {\n    return usm.serializeURLOrigin(this._url);\n  }\n\n  get protocol() {\n    return this._url.scheme + \":\";\n  }\n\n  set protocol(v) {\n    usm.basicURLParse(v + \":\", { url: this._url, stateOverride: \"scheme start\" });\n  }\n\n  get username() {\n    return this._url.username;\n  }\n\n  set username(v) {\n    if (usm.cannotHaveAUsernamePasswordPort(this._url)) {\n      return;\n    }\n\n    usm.setTheUsername(this._url, v);\n  }\n\n  get password() {\n    return this._url.password;\n  }\n\n  set password(v) {\n    if (usm.cannotHaveAUsernamePasswordPort(this._url)) {\n      return;\n    }\n\n    usm.setThePassword(this._url, v);\n  }\n\n  get host() {\n    const url = this._url;\n\n    if (url.host === null) {\n      return \"\";\n    }\n\n    if (url.port === null) {\n      return usm.serializeHost(url.host);\n    }\n\n    return usm.serializeHost(url.host) + \":\" + usm.serializeInteger(url.port);\n  }\n\n  set host(v) {\n    if (this._url.cannotBeABaseURL) {\n      return;\n    }\n\n    usm.basicURLParse(v, { url: this._url, stateOverride: \"host\" });\n  }\n\n  get hostname() {\n    if (this._url.host === null) {\n      return \"\";\n    }\n\n    return usm.serializeHost(this._url.host);\n  }\n\n  set hostname(v) {\n    if (this._url.cannotBeABaseURL) {\n      return;\n    }\n\n    usm.basicURLParse(v, { url: this._url, stateOverride: \"hostname\" });\n  }\n\n  get port() {\n    if (this._url.port === null) {\n      return \"\";\n    }\n\n    return usm.serializeInteger(this._url.port);\n  }\n\n  set port(v) {\n    if (usm.cannotHaveAUsernamePasswordPort(this._url)) {\n      return;\n    }\n\n    if (v === \"\") {\n      this._url.port = null;\n    } else {\n      usm.basicURLParse(v, { url: this._url, stateOverride: \"port\" });\n    }\n  }\n\n  get pathname() {\n    if (this._url.cannotBeABaseURL) {\n      return this._url.path[0];\n    }\n\n    if (this._url.path.length === 0) {\n      return \"\";\n    }\n\n    return \"/\" + this._url.path.join(\"/\");\n  }\n\n  set pathname(v) {\n    if (this._url.cannotBeABaseURL) {\n      return;\n    }\n\n    this._url.path = [];\n    usm.basicURLParse(v, { url: this._url, stateOverride: \"path start\" });\n  }\n\n  get search() {\n    if (this._url.query === null || this._url.query === \"\") {\n      return \"\";\n    }\n\n    return \"?\" + this._url.query;\n  }\n\n  set search(v) {\n    // TODO: query stuff\n\n    const url = this._url;\n\n    if (v === \"\") {\n      url.query = null;\n      return;\n    }\n\n    const input = v[0] === \"?\" ? v.substring(1) : v;\n    url.query = \"\";\n    usm.basicURLParse(input, { url, stateOverride: \"query\" });\n  }\n\n  get hash() {\n    if (this._url.fragment === null || this._url.fragment === \"\") {\n      return \"\";\n    }\n\n    return \"#\" + this._url.fragment;\n  }\n\n  set hash(v) {\n    if (v === \"\") {\n      this._url.fragment = null;\n      return;\n    }\n\n    const input = v[0] === \"#\" ? v.substring(1) : v;\n    this._url.fragment = \"\";\n    usm.basicURLParse(input, { url: this._url, stateOverride: \"fragment\" });\n  }\n\n  toJSON() {\n    return this.href;\n  }\n};\n\n\n/***/ }),\n\n/***/ 3394:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nconst conversions = __webpack_require__(4886);\nconst utils = __webpack_require__(3185);\nconst Impl = __webpack_require__(7537);\n\nconst impl = utils.implSymbol;\n\nfunction URL(url) {\n  if (!this || this[impl] || !(this instanceof URL)) {\n    throw new TypeError(\"Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function.\");\n  }\n  if (arguments.length < 1) {\n    throw new TypeError(\"Failed to construct 'URL': 1 argument required, but only \" + arguments.length + \" present.\");\n  }\n  const args = [];\n  for (let i = 0; i < arguments.length && i < 2; ++i) {\n    args[i] = arguments[i];\n  }\n  args[0] = conversions[\"USVString\"](args[0]);\n  if (args[1] !== undefined) {\n  args[1] = conversions[\"USVString\"](args[1]);\n  }\n\n  module.exports.setup(this, args);\n}\n\nURL.prototype.toJSON = function toJSON() {\n  if (!this || !module.exports.is(this)) {\n    throw new TypeError(\"Illegal invocation\");\n  }\n  const args = [];\n  for (let i = 0; i < arguments.length && i < 0; ++i) {\n    args[i] = arguments[i];\n  }\n  return this[impl].toJSON.apply(this[impl], args);\n};\nObject.defineProperty(URL.prototype, \"href\", {\n  get() {\n    return this[impl].href;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].href = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nURL.prototype.toString = function () {\n  if (!this || !module.exports.is(this)) {\n    throw new TypeError(\"Illegal invocation\");\n  }\n  return this.href;\n};\n\nObject.defineProperty(URL.prototype, \"origin\", {\n  get() {\n    return this[impl].origin;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"protocol\", {\n  get() {\n    return this[impl].protocol;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].protocol = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"username\", {\n  get() {\n    return this[impl].username;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].username = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"password\", {\n  get() {\n    return this[impl].password;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].password = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"host\", {\n  get() {\n    return this[impl].host;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].host = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"hostname\", {\n  get() {\n    return this[impl].hostname;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].hostname = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"port\", {\n  get() {\n    return this[impl].port;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].port = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"pathname\", {\n  get() {\n    return this[impl].pathname;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].pathname = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"search\", {\n  get() {\n    return this[impl].search;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].search = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\nObject.defineProperty(URL.prototype, \"hash\", {\n  get() {\n    return this[impl].hash;\n  },\n  set(V) {\n    V = conversions[\"USVString\"](V);\n    this[impl].hash = V;\n  },\n  enumerable: true,\n  configurable: true\n});\n\n\nmodule.exports = {\n  is(obj) {\n    return !!obj && obj[impl] instanceof Impl.implementation;\n  },\n  create(constructorArgs, privateData) {\n    let obj = Object.create(URL.prototype);\n    this.setup(obj, constructorArgs, privateData);\n    return obj;\n  },\n  setup(obj, constructorArgs, privateData) {\n    if (!privateData) privateData = {};\n    privateData.wrapper = obj;\n\n    obj[impl] = new Impl.implementation(constructorArgs, privateData);\n    obj[impl][utils.wrapperSymbol] = obj;\n  },\n  interface: URL,\n  expose: {\n    Window: { URL: URL },\n    Worker: { URL: URL }\n  }\n};\n\n\n\n/***/ }),\n\n/***/ 8665:\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n\nexports.URL = __webpack_require__(3394).interface;\nexports.serializeURL = __webpack_require__(2158).serializeURL;\nexports.serializeURLOrigin = __webpack_require__(2158).serializeURLOrigin;\nexports.basicURLParse = __webpack_require__(2158).basicURLParse;\nexports.setTheUsername = __webpack_require__(2158).setTheUsername;\nexports.setThePassword = __webpack_require__(2158).setThePassword;\nexports.serializeHost = __webpack_require__(2158).serializeHost;\nexports.serializeInteger = __webpack_require__(2158).serializeInteger;\nexports.parseURL = __webpack_require__(2158).parseURL;\n\n\n/***/ }),\n\n/***/ 2158:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\"use strict\";\n\r\nconst punycode = __webpack_require__(4213);\r\nconst tr46 = __webpack_require__(4256);\r\n\r\nconst specialSchemes = {\r\n  ftp: 21,\r\n  file: null,\r\n  gopher: 70,\r\n  http: 80,\r\n  https: 443,\r\n  ws: 80,\r\n  wss: 443\r\n};\r\n\r\nconst failure = Symbol(\"failure\");\r\n\r\nfunction countSymbols(str) {\r\n  return punycode.ucs2.decode(str).length;\r\n}\r\n\r\nfunction at(input, idx) {\r\n  const c = input[idx];\r\n  return isNaN(c) ? undefined : String.fromCodePoint(c);\r\n}\r\n\r\nfunction isASCIIDigit(c) {\r\n  return c >= 0x30 && c <= 0x39;\r\n}\r\n\r\nfunction isASCIIAlpha(c) {\r\n  return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A);\r\n}\r\n\r\nfunction isASCIIAlphanumeric(c) {\r\n  return isASCIIAlpha(c) || isASCIIDigit(c);\r\n}\r\n\r\nfunction isASCIIHex(c) {\r\n  return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66);\r\n}\r\n\r\nfunction isSingleDot(buffer) {\r\n  return buffer === \".\" || buffer.toLowerCase() === \"%2e\";\r\n}\r\n\r\nfunction isDoubleDot(buffer) {\r\n  buffer = buffer.toLowerCase();\r\n  return buffer === \"..\" || buffer === \"%2e.\" || buffer === \".%2e\" || buffer === \"%2e%2e\";\r\n}\r\n\r\nfunction isWindowsDriveLetterCodePoints(cp1, cp2) {\r\n  return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124);\r\n}\r\n\r\nfunction isWindowsDriveLetterString(string) {\r\n  return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === \":\" || string[1] === \"|\");\r\n}\r\n\r\nfunction isNormalizedWindowsDriveLetterString(string) {\r\n  return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === \":\";\r\n}\r\n\r\nfunction containsForbiddenHostCodePoint(string) {\r\n  return string.search(/\\u0000|\\u0009|\\u000A|\\u000D|\\u0020|#|%|\\/|:|\\?|@|\\[|\\\\|\\]/) !== -1;\r\n}\r\n\r\nfunction containsForbiddenHostCodePointExcludingPercent(string) {\r\n  return string.search(/\\u0000|\\u0009|\\u000A|\\u000D|\\u0020|#|\\/|:|\\?|@|\\[|\\\\|\\]/) !== -1;\r\n}\r\n\r\nfunction isSpecialScheme(scheme) {\r\n  return specialSchemes[scheme] !== undefined;\r\n}\r\n\r\nfunction isSpecial(url) {\r\n  return isSpecialScheme(url.scheme);\r\n}\r\n\r\nfunction defaultPort(scheme) {\r\n  return specialSchemes[scheme];\r\n}\r\n\r\nfunction percentEncode(c) {\r\n  let hex = c.toString(16).toUpperCase();\r\n  if (hex.length === 1) {\r\n    hex = \"0\" + hex;\r\n  }\r\n\r\n  return \"%\" + hex;\r\n}\r\n\r\nfunction utf8PercentEncode(c) {\r\n  const buf = new Buffer(c);\r\n\r\n  let str = \"\";\r\n\r\n  for (let i = 0; i < buf.length; ++i) {\r\n    str += percentEncode(buf[i]);\r\n  }\r\n\r\n  return str;\r\n}\r\n\r\nfunction utf8PercentDecode(str) {\r\n  const input = new Buffer(str);\r\n  const output = [];\r\n  for (let i = 0; i < input.length; ++i) {\r\n    if (input[i] !== 37) {\r\n      output.push(input[i]);\r\n    } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) {\r\n      output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16));\r\n      i += 2;\r\n    } else {\r\n      output.push(input[i]);\r\n    }\r\n  }\r\n  return new Buffer(output).toString();\r\n}\r\n\r\nfunction isC0ControlPercentEncode(c) {\r\n  return c <= 0x1F || c > 0x7E;\r\n}\r\n\r\nconst extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]);\r\nfunction isPathPercentEncode(c) {\r\n  return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c);\r\n}\r\n\r\nconst extraUserinfoPercentEncodeSet =\r\n  new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]);\r\nfunction isUserinfoPercentEncode(c) {\r\n  return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c);\r\n}\r\n\r\nfunction percentEncodeChar(c, encodeSetPredicate) {\r\n  const cStr = String.fromCodePoint(c);\r\n\r\n  if (encodeSetPredicate(c)) {\r\n    return utf8PercentEncode(cStr);\r\n  }\r\n\r\n  return cStr;\r\n}\r\n\r\nfunction parseIPv4Number(input) {\r\n  let R = 10;\r\n\r\n  if (input.length >= 2 && input.charAt(0) === \"0\" && input.charAt(1).toLowerCase() === \"x\") {\r\n    input = input.substring(2);\r\n    R = 16;\r\n  } else if (input.length >= 2 && input.charAt(0) === \"0\") {\r\n    input = input.substring(1);\r\n    R = 8;\r\n  }\r\n\r\n  if (input === \"\") {\r\n    return 0;\r\n  }\r\n\r\n  const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/);\r\n  if (regex.test(input)) {\r\n    return failure;\r\n  }\r\n\r\n  return parseInt(input, R);\r\n}\r\n\r\nfunction parseIPv4(input) {\r\n  const parts = input.split(\".\");\r\n  if (parts[parts.length - 1] === \"\") {\r\n    if (parts.length > 1) {\r\n      parts.pop();\r\n    }\r\n  }\r\n\r\n  if (parts.length > 4) {\r\n    return input;\r\n  }\r\n\r\n  const numbers = [];\r\n  for (const part of parts) {\r\n    if (part === \"\") {\r\n      return input;\r\n    }\r\n    const n = parseIPv4Number(part);\r\n    if (n === failure) {\r\n      return input;\r\n    }\r\n\r\n    numbers.push(n);\r\n  }\r\n\r\n  for (let i = 0; i < numbers.length - 1; ++i) {\r\n    if (numbers[i] > 255) {\r\n      return failure;\r\n    }\r\n  }\r\n  if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) {\r\n    return failure;\r\n  }\r\n\r\n  let ipv4 = numbers.pop();\r\n  let counter = 0;\r\n\r\n  for (const n of numbers) {\r\n    ipv4 += n * Math.pow(256, 3 - counter);\r\n    ++counter;\r\n  }\r\n\r\n  return ipv4;\r\n}\r\n\r\nfunction serializeIPv4(address) {\r\n  let output = \"\";\r\n  let n = address;\r\n\r\n  for (let i = 1; i <= 4; ++i) {\r\n    output = String(n % 256) + output;\r\n    if (i !== 4) {\r\n      output = \".\" + output;\r\n    }\r\n    n = Math.floor(n / 256);\r\n  }\r\n\r\n  return output;\r\n}\r\n\r\nfunction parseIPv6(input) {\r\n  const address = [0, 0, 0, 0, 0, 0, 0, 0];\r\n  let pieceIndex = 0;\r\n  let compress = null;\r\n  let pointer = 0;\r\n\r\n  input = punycode.ucs2.decode(input);\r\n\r\n  if (input[pointer] === 58) {\r\n    if (input[pointer + 1] !== 58) {\r\n      return failure;\r\n    }\r\n\r\n    pointer += 2;\r\n    ++pieceIndex;\r\n    compress = pieceIndex;\r\n  }\r\n\r\n  while (pointer < input.length) {\r\n    if (pieceIndex === 8) {\r\n      return failure;\r\n    }\r\n\r\n    if (input[pointer] === 58) {\r\n      if (compress !== null) {\r\n        return failure;\r\n      }\r\n      ++pointer;\r\n      ++pieceIndex;\r\n      compress = pieceIndex;\r\n      continue;\r\n    }\r\n\r\n    let value = 0;\r\n    let length = 0;\r\n\r\n    while (length < 4 && isASCIIHex(input[pointer])) {\r\n      value = value * 0x10 + parseInt(at(input, pointer), 16);\r\n      ++pointer;\r\n      ++length;\r\n    }\r\n\r\n    if (input[pointer] === 46) {\r\n      if (length === 0) {\r\n        return failure;\r\n      }\r\n\r\n      pointer -= length;\r\n\r\n      if (pieceIndex > 6) {\r\n        return failure;\r\n      }\r\n\r\n      let numbersSeen = 0;\r\n\r\n      while (input[pointer] !== undefined) {\r\n        let ipv4Piece = null;\r\n\r\n        if (numbersSeen > 0) {\r\n          if (input[pointer] === 46 && numbersSeen < 4) {\r\n            ++pointer;\r\n          } else {\r\n            return failure;\r\n          }\r\n        }\r\n\r\n        if (!isASCIIDigit(input[pointer])) {\r\n          return failure;\r\n        }\r\n\r\n        while (isASCIIDigit(input[pointer])) {\r\n          const number = parseInt(at(input, pointer));\r\n          if (ipv4Piece === null) {\r\n            ipv4Piece = number;\r\n          } else if (ipv4Piece === 0) {\r\n            return failure;\r\n          } else {\r\n            ipv4Piece = ipv4Piece * 10 + number;\r\n          }\r\n          if (ipv4Piece > 255) {\r\n            return failure;\r\n          }\r\n          ++pointer;\r\n        }\r\n\r\n        address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece;\r\n\r\n        ++numbersSeen;\r\n\r\n        if (numbersSeen === 2 || numbersSeen === 4) {\r\n          ++pieceIndex;\r\n        }\r\n      }\r\n\r\n      if (numbersSeen !== 4) {\r\n        return failure;\r\n      }\r\n\r\n      break;\r\n    } else if (input[pointer] === 58) {\r\n      ++pointer;\r\n      if (input[pointer] === undefined) {\r\n        return failure;\r\n      }\r\n    } else if (input[pointer] !== undefined) {\r\n      return failure;\r\n    }\r\n\r\n    address[pieceIndex] = value;\r\n    ++pieceIndex;\r\n  }\r\n\r\n  if (compress !== null) {\r\n    let swaps = pieceIndex - compress;\r\n    pieceIndex = 7;\r\n    while (pieceIndex !== 0 && swaps > 0) {\r\n      const temp = address[compress + swaps - 1];\r\n      address[compress + swaps - 1] = address[pieceIndex];\r\n      address[pieceIndex] = temp;\r\n      --pieceIndex;\r\n      --swaps;\r\n    }\r\n  } else if (compress === null && pieceIndex !== 8) {\r\n    return failure;\r\n  }\r\n\r\n  return address;\r\n}\r\n\r\nfunction serializeIPv6(address) {\r\n  let output = \"\";\r\n  const seqResult = findLongestZeroSequence(address);\r\n  const compress = seqResult.idx;\r\n  let ignore0 = false;\r\n\r\n  for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) {\r\n    if (ignore0 && address[pieceIndex] === 0) {\r\n      continue;\r\n    } else if (ignore0) {\r\n      ignore0 = false;\r\n    }\r\n\r\n    if (compress === pieceIndex) {\r\n      const separator = pieceIndex === 0 ? \"::\" : \":\";\r\n      output += separator;\r\n      ignore0 = true;\r\n      continue;\r\n    }\r\n\r\n    output += address[pieceIndex].toString(16);\r\n\r\n    if (pieceIndex !== 7) {\r\n      output += \":\";\r\n    }\r\n  }\r\n\r\n  return output;\r\n}\r\n\r\nfunction parseHost(input, isSpecialArg) {\r\n  if (input[0] === \"[\") {\r\n    if (input[input.length - 1] !== \"]\") {\r\n      return failure;\r\n    }\r\n\r\n    return parseIPv6(input.substring(1, input.length - 1));\r\n  }\r\n\r\n  if (!isSpecialArg) {\r\n    return parseOpaqueHost(input);\r\n  }\r\n\r\n  const domain = utf8PercentDecode(input);\r\n  const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false);\r\n  if (asciiDomain === null) {\r\n    return failure;\r\n  }\r\n\r\n  if (containsForbiddenHostCodePoint(asciiDomain)) {\r\n    return failure;\r\n  }\r\n\r\n  const ipv4Host = parseIPv4(asciiDomain);\r\n  if (typeof ipv4Host === \"number\" || ipv4Host === failure) {\r\n    return ipv4Host;\r\n  }\r\n\r\n  return asciiDomain;\r\n}\r\n\r\nfunction parseOpaqueHost(input) {\r\n  if (containsForbiddenHostCodePointExcludingPercent(input)) {\r\n    return failure;\r\n  }\r\n\r\n  let output = \"\";\r\n  const decoded = punycode.ucs2.decode(input);\r\n  for (let i = 0; i < decoded.length; ++i) {\r\n    output += percentEncodeChar(decoded[i], isC0ControlPercentEncode);\r\n  }\r\n  return output;\r\n}\r\n\r\nfunction findLongestZeroSequence(arr) {\r\n  let maxIdx = null;\r\n  let maxLen = 1; // only find elements > 1\r\n  let currStart = null;\r\n  let currLen = 0;\r\n\r\n  for (let i = 0; i < arr.length; ++i) {\r\n    if (arr[i] !== 0) {\r\n      if (currLen > maxLen) {\r\n        maxIdx = currStart;\r\n        maxLen = currLen;\r\n      }\r\n\r\n      currStart = null;\r\n      currLen = 0;\r\n    } else {\r\n      if (currStart === null) {\r\n        currStart = i;\r\n      }\r\n      ++currLen;\r\n    }\r\n  }\r\n\r\n  // if trailing zeros\r\n  if (currLen > maxLen) {\r\n    maxIdx = currStart;\r\n    maxLen = currLen;\r\n  }\r\n\r\n  return {\r\n    idx: maxIdx,\r\n    len: maxLen\r\n  };\r\n}\r\n\r\nfunction serializeHost(host) {\r\n  if (typeof host === \"number\") {\r\n    return serializeIPv4(host);\r\n  }\r\n\r\n  // IPv6 serializer\r\n  if (host instanceof Array) {\r\n    return \"[\" + serializeIPv6(host) + \"]\";\r\n  }\r\n\r\n  return host;\r\n}\r\n\r\nfunction trimControlChars(url) {\r\n  return url.replace(/^[\\u0000-\\u001F\\u0020]+|[\\u0000-\\u001F\\u0020]+$/g, \"\");\r\n}\r\n\r\nfunction trimTabAndNewline(url) {\r\n  return url.replace(/\\u0009|\\u000A|\\u000D/g, \"\");\r\n}\r\n\r\nfunction shortenPath(url) {\r\n  const path = url.path;\r\n  if (path.length === 0) {\r\n    return;\r\n  }\r\n  if (url.scheme === \"file\" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) {\r\n    return;\r\n  }\r\n\r\n  path.pop();\r\n}\r\n\r\nfunction includesCredentials(url) {\r\n  return url.username !== \"\" || url.password !== \"\";\r\n}\r\n\r\nfunction cannotHaveAUsernamePasswordPort(url) {\r\n  return url.host === null || url.host === \"\" || url.cannotBeABaseURL || url.scheme === \"file\";\r\n}\r\n\r\nfunction isNormalizedWindowsDriveLetter(string) {\r\n  return /^[A-Za-z]:$/.test(string);\r\n}\r\n\r\nfunction URLStateMachine(input, base, encodingOverride, url, stateOverride) {\r\n  this.pointer = 0;\r\n  this.input = input;\r\n  this.base = base || null;\r\n  this.encodingOverride = encodingOverride || \"utf-8\";\r\n  this.stateOverride = stateOverride;\r\n  this.url = url;\r\n  this.failure = false;\r\n  this.parseError = false;\r\n\r\n  if (!this.url) {\r\n    this.url = {\r\n      scheme: \"\",\r\n      username: \"\",\r\n      password: \"\",\r\n      host: null,\r\n      port: null,\r\n      path: [],\r\n      query: null,\r\n      fragment: null,\r\n\r\n      cannotBeABaseURL: false\r\n    };\r\n\r\n    const res = trimControlChars(this.input);\r\n    if (res !== this.input) {\r\n      this.parseError = true;\r\n    }\r\n    this.input = res;\r\n  }\r\n\r\n  const res = trimTabAndNewline(this.input);\r\n  if (res !== this.input) {\r\n    this.parseError = true;\r\n  }\r\n  this.input = res;\r\n\r\n  this.state = stateOverride || \"scheme start\";\r\n\r\n  this.buffer = \"\";\r\n  this.atFlag = false;\r\n  this.arrFlag = false;\r\n  this.passwordTokenSeenFlag = false;\r\n\r\n  this.input = punycode.ucs2.decode(this.input);\r\n\r\n  for (; this.pointer <= this.input.length; ++this.pointer) {\r\n    const c = this.input[this.pointer];\r\n    const cStr = isNaN(c) ? undefined : String.fromCodePoint(c);\r\n\r\n    // exec state machine\r\n    const ret = this[\"parse \" + this.state](c, cStr);\r\n    if (!ret) {\r\n      break; // terminate algorithm\r\n    } else if (ret === failure) {\r\n      this.failure = true;\r\n      break;\r\n    }\r\n  }\r\n}\r\n\r\nURLStateMachine.prototype[\"parse scheme start\"] = function parseSchemeStart(c, cStr) {\r\n  if (isASCIIAlpha(c)) {\r\n    this.buffer += cStr.toLowerCase();\r\n    this.state = \"scheme\";\r\n  } else if (!this.stateOverride) {\r\n    this.state = \"no scheme\";\r\n    --this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n    return failure;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse scheme\"] = function parseScheme(c, cStr) {\r\n  if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) {\r\n    this.buffer += cStr.toLowerCase();\r\n  } else if (c === 58) {\r\n    if (this.stateOverride) {\r\n      if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) {\r\n        return false;\r\n      }\r\n\r\n      if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) {\r\n        return false;\r\n      }\r\n\r\n      if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === \"file\") {\r\n        return false;\r\n      }\r\n\r\n      if (this.url.scheme === \"file\" && (this.url.host === \"\" || this.url.host === null)) {\r\n        return false;\r\n      }\r\n    }\r\n    this.url.scheme = this.buffer;\r\n    this.buffer = \"\";\r\n    if (this.stateOverride) {\r\n      return false;\r\n    }\r\n    if (this.url.scheme === \"file\") {\r\n      if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) {\r\n        this.parseError = true;\r\n      }\r\n      this.state = \"file\";\r\n    } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) {\r\n      this.state = \"special relative or authority\";\r\n    } else if (isSpecial(this.url)) {\r\n      this.state = \"special authority slashes\";\r\n    } else if (this.input[this.pointer + 1] === 47) {\r\n      this.state = \"path or authority\";\r\n      ++this.pointer;\r\n    } else {\r\n      this.url.cannotBeABaseURL = true;\r\n      this.url.path.push(\"\");\r\n      this.state = \"cannot-be-a-base-URL path\";\r\n    }\r\n  } else if (!this.stateOverride) {\r\n    this.buffer = \"\";\r\n    this.state = \"no scheme\";\r\n    this.pointer = -1;\r\n  } else {\r\n    this.parseError = true;\r\n    return failure;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse no scheme\"] = function parseNoScheme(c) {\r\n  if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) {\r\n    return failure;\r\n  } else if (this.base.cannotBeABaseURL && c === 35) {\r\n    this.url.scheme = this.base.scheme;\r\n    this.url.path = this.base.path.slice();\r\n    this.url.query = this.base.query;\r\n    this.url.fragment = \"\";\r\n    this.url.cannotBeABaseURL = true;\r\n    this.state = \"fragment\";\r\n  } else if (this.base.scheme === \"file\") {\r\n    this.state = \"file\";\r\n    --this.pointer;\r\n  } else {\r\n    this.state = \"relative\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse special relative or authority\"] = function parseSpecialRelativeOrAuthority(c) {\r\n  if (c === 47 && this.input[this.pointer + 1] === 47) {\r\n    this.state = \"special authority ignore slashes\";\r\n    ++this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n    this.state = \"relative\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse path or authority\"] = function parsePathOrAuthority(c) {\r\n  if (c === 47) {\r\n    this.state = \"authority\";\r\n  } else {\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse relative\"] = function parseRelative(c) {\r\n  this.url.scheme = this.base.scheme;\r\n  if (isNaN(c)) {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.url.path = this.base.path.slice();\r\n    this.url.query = this.base.query;\r\n  } else if (c === 47) {\r\n    this.state = \"relative slash\";\r\n  } else if (c === 63) {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.url.path = this.base.path.slice();\r\n    this.url.query = \"\";\r\n    this.state = \"query\";\r\n  } else if (c === 35) {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.url.path = this.base.path.slice();\r\n    this.url.query = this.base.query;\r\n    this.url.fragment = \"\";\r\n    this.state = \"fragment\";\r\n  } else if (isSpecial(this.url) && c === 92) {\r\n    this.parseError = true;\r\n    this.state = \"relative slash\";\r\n  } else {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.url.path = this.base.path.slice(0, this.base.path.length - 1);\r\n\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse relative slash\"] = function parseRelativeSlash(c) {\r\n  if (isSpecial(this.url) && (c === 47 || c === 92)) {\r\n    if (c === 92) {\r\n      this.parseError = true;\r\n    }\r\n    this.state = \"special authority ignore slashes\";\r\n  } else if (c === 47) {\r\n    this.state = \"authority\";\r\n  } else {\r\n    this.url.username = this.base.username;\r\n    this.url.password = this.base.password;\r\n    this.url.host = this.base.host;\r\n    this.url.port = this.base.port;\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse special authority slashes\"] = function parseSpecialAuthoritySlashes(c) {\r\n  if (c === 47 && this.input[this.pointer + 1] === 47) {\r\n    this.state = \"special authority ignore slashes\";\r\n    ++this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n    this.state = \"special authority ignore slashes\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse special authority ignore slashes\"] = function parseSpecialAuthorityIgnoreSlashes(c) {\r\n  if (c !== 47 && c !== 92) {\r\n    this.state = \"authority\";\r\n    --this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse authority\"] = function parseAuthority(c, cStr) {\r\n  if (c === 64) {\r\n    this.parseError = true;\r\n    if (this.atFlag) {\r\n      this.buffer = \"%40\" + this.buffer;\r\n    }\r\n    this.atFlag = true;\r\n\r\n    // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars\r\n    const len = countSymbols(this.buffer);\r\n    for (let pointer = 0; pointer < len; ++pointer) {\r\n      const codePoint = this.buffer.codePointAt(pointer);\r\n\r\n      if (codePoint === 58 && !this.passwordTokenSeenFlag) {\r\n        this.passwordTokenSeenFlag = true;\r\n        continue;\r\n      }\r\n      const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode);\r\n      if (this.passwordTokenSeenFlag) {\r\n        this.url.password += encodedCodePoints;\r\n      } else {\r\n        this.url.username += encodedCodePoints;\r\n      }\r\n    }\r\n    this.buffer = \"\";\r\n  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||\r\n             (isSpecial(this.url) && c === 92)) {\r\n    if (this.atFlag && this.buffer === \"\") {\r\n      this.parseError = true;\r\n      return failure;\r\n    }\r\n    this.pointer -= countSymbols(this.buffer) + 1;\r\n    this.buffer = \"\";\r\n    this.state = \"host\";\r\n  } else {\r\n    this.buffer += cStr;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse hostname\"] =\r\nURLStateMachine.prototype[\"parse host\"] = function parseHostName(c, cStr) {\r\n  if (this.stateOverride && this.url.scheme === \"file\") {\r\n    --this.pointer;\r\n    this.state = \"file host\";\r\n  } else if (c === 58 && !this.arrFlag) {\r\n    if (this.buffer === \"\") {\r\n      this.parseError = true;\r\n      return failure;\r\n    }\r\n\r\n    const host = parseHost(this.buffer, isSpecial(this.url));\r\n    if (host === failure) {\r\n      return failure;\r\n    }\r\n\r\n    this.url.host = host;\r\n    this.buffer = \"\";\r\n    this.state = \"port\";\r\n    if (this.stateOverride === \"hostname\") {\r\n      return false;\r\n    }\r\n  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||\r\n             (isSpecial(this.url) && c === 92)) {\r\n    --this.pointer;\r\n    if (isSpecial(this.url) && this.buffer === \"\") {\r\n      this.parseError = true;\r\n      return failure;\r\n    } else if (this.stateOverride && this.buffer === \"\" &&\r\n               (includesCredentials(this.url) || this.url.port !== null)) {\r\n      this.parseError = true;\r\n      return false;\r\n    }\r\n\r\n    const host = parseHost(this.buffer, isSpecial(this.url));\r\n    if (host === failure) {\r\n      return failure;\r\n    }\r\n\r\n    this.url.host = host;\r\n    this.buffer = \"\";\r\n    this.state = \"path start\";\r\n    if (this.stateOverride) {\r\n      return false;\r\n    }\r\n  } else {\r\n    if (c === 91) {\r\n      this.arrFlag = true;\r\n    } else if (c === 93) {\r\n      this.arrFlag = false;\r\n    }\r\n    this.buffer += cStr;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse port\"] = function parsePort(c, cStr) {\r\n  if (isASCIIDigit(c)) {\r\n    this.buffer += cStr;\r\n  } else if (isNaN(c) || c === 47 || c === 63 || c === 35 ||\r\n             (isSpecial(this.url) && c === 92) ||\r\n             this.stateOverride) {\r\n    if (this.buffer !== \"\") {\r\n      const port = parseInt(this.buffer);\r\n      if (port > Math.pow(2, 16) - 1) {\r\n        this.parseError = true;\r\n        return failure;\r\n      }\r\n      this.url.port = port === defaultPort(this.url.scheme) ? null : port;\r\n      this.buffer = \"\";\r\n    }\r\n    if (this.stateOverride) {\r\n      return false;\r\n    }\r\n    this.state = \"path start\";\r\n    --this.pointer;\r\n  } else {\r\n    this.parseError = true;\r\n    return failure;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nconst fileOtherwiseCodePoints = new Set([47, 92, 63, 35]);\r\n\r\nURLStateMachine.prototype[\"parse file\"] = function parseFile(c) {\r\n  this.url.scheme = \"file\";\r\n\r\n  if (c === 47 || c === 92) {\r\n    if (c === 92) {\r\n      this.parseError = true;\r\n    }\r\n    this.state = \"file slash\";\r\n  } else if (this.base !== null && this.base.scheme === \"file\") {\r\n    if (isNaN(c)) {\r\n      this.url.host = this.base.host;\r\n      this.url.path = this.base.path.slice();\r\n      this.url.query = this.base.query;\r\n    } else if (c === 63) {\r\n      this.url.host = this.base.host;\r\n      this.url.path = this.base.path.slice();\r\n      this.url.query = \"\";\r\n      this.state = \"query\";\r\n    } else if (c === 35) {\r\n      this.url.host = this.base.host;\r\n      this.url.path = this.base.path.slice();\r\n      this.url.query = this.base.query;\r\n      this.url.fragment = \"\";\r\n      this.state = \"fragment\";\r\n    } else {\r\n      if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points\r\n          !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) ||\r\n          (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points\r\n           !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) {\r\n        this.url.host = this.base.host;\r\n        this.url.path = this.base.path.slice();\r\n        shortenPath(this.url);\r\n      } else {\r\n        this.parseError = true;\r\n      }\r\n\r\n      this.state = \"path\";\r\n      --this.pointer;\r\n    }\r\n  } else {\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse file slash\"] = function parseFileSlash(c) {\r\n  if (c === 47 || c === 92) {\r\n    if (c === 92) {\r\n      this.parseError = true;\r\n    }\r\n    this.state = \"file host\";\r\n  } else {\r\n    if (this.base !== null && this.base.scheme === \"file\") {\r\n      if (isNormalizedWindowsDriveLetterString(this.base.path[0])) {\r\n        this.url.path.push(this.base.path[0]);\r\n      } else {\r\n        this.url.host = this.base.host;\r\n      }\r\n    }\r\n    this.state = \"path\";\r\n    --this.pointer;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse file host\"] = function parseFileHost(c, cStr) {\r\n  if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) {\r\n    --this.pointer;\r\n    if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) {\r\n      this.parseError = true;\r\n      this.state = \"path\";\r\n    } else if (this.buffer === \"\") {\r\n      this.url.host = \"\";\r\n      if (this.stateOverride) {\r\n        return false;\r\n      }\r\n      this.state = \"path start\";\r\n    } else {\r\n      let host = parseHost(this.buffer, isSpecial(this.url));\r\n      if (host === failure) {\r\n        return failure;\r\n      }\r\n      if (host === \"localhost\") {\r\n        host = \"\";\r\n      }\r\n      this.url.host = host;\r\n\r\n      if (this.stateOverride) {\r\n        return false;\r\n      }\r\n\r\n      this.buffer = \"\";\r\n      this.state = \"path start\";\r\n    }\r\n  } else {\r\n    this.buffer += cStr;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse path start\"] = function parsePathStart(c) {\r\n  if (isSpecial(this.url)) {\r\n    if (c === 92) {\r\n      this.parseError = true;\r\n    }\r\n    this.state = \"path\";\r\n\r\n    if (c !== 47 && c !== 92) {\r\n      --this.pointer;\r\n    }\r\n  } else if (!this.stateOverride && c === 63) {\r\n    this.url.query = \"\";\r\n    this.state = \"query\";\r\n  } else if (!this.stateOverride && c === 35) {\r\n    this.url.fragment = \"\";\r\n    this.state = \"fragment\";\r\n  } else if (c !== undefined) {\r\n    this.state = \"path\";\r\n    if (c !== 47) {\r\n      --this.pointer;\r\n    }\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse path\"] = function parsePath(c) {\r\n  if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) ||\r\n      (!this.stateOverride && (c === 63 || c === 35))) {\r\n    if (isSpecial(this.url) && c === 92) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    if (isDoubleDot(this.buffer)) {\r\n      shortenPath(this.url);\r\n      if (c !== 47 && !(isSpecial(this.url) && c === 92)) {\r\n        this.url.path.push(\"\");\r\n      }\r\n    } else if (isSingleDot(this.buffer) && c !== 47 &&\r\n               !(isSpecial(this.url) && c === 92)) {\r\n      this.url.path.push(\"\");\r\n    } else if (!isSingleDot(this.buffer)) {\r\n      if (this.url.scheme === \"file\" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) {\r\n        if (this.url.host !== \"\" && this.url.host !== null) {\r\n          this.parseError = true;\r\n          this.url.host = \"\";\r\n        }\r\n        this.buffer = this.buffer[0] + \":\";\r\n      }\r\n      this.url.path.push(this.buffer);\r\n    }\r\n    this.buffer = \"\";\r\n    if (this.url.scheme === \"file\" && (c === undefined || c === 63 || c === 35)) {\r\n      while (this.url.path.length > 1 && this.url.path[0] === \"\") {\r\n        this.parseError = true;\r\n        this.url.path.shift();\r\n      }\r\n    }\r\n    if (c === 63) {\r\n      this.url.query = \"\";\r\n      this.state = \"query\";\r\n    }\r\n    if (c === 35) {\r\n      this.url.fragment = \"\";\r\n      this.state = \"fragment\";\r\n    }\r\n  } else {\r\n    // TODO: If c is not a URL code point and not \"%\", parse error.\r\n\r\n    if (c === 37 &&\r\n      (!isASCIIHex(this.input[this.pointer + 1]) ||\r\n        !isASCIIHex(this.input[this.pointer + 2]))) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    this.buffer += percentEncodeChar(c, isPathPercentEncode);\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse cannot-be-a-base-URL path\"] = function parseCannotBeABaseURLPath(c) {\r\n  if (c === 63) {\r\n    this.url.query = \"\";\r\n    this.state = \"query\";\r\n  } else if (c === 35) {\r\n    this.url.fragment = \"\";\r\n    this.state = \"fragment\";\r\n  } else {\r\n    // TODO: Add: not a URL code point\r\n    if (!isNaN(c) && c !== 37) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    if (c === 37 &&\r\n        (!isASCIIHex(this.input[this.pointer + 1]) ||\r\n         !isASCIIHex(this.input[this.pointer + 2]))) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    if (!isNaN(c)) {\r\n      this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode);\r\n    }\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse query\"] = function parseQuery(c, cStr) {\r\n  if (isNaN(c) || (!this.stateOverride && c === 35)) {\r\n    if (!isSpecial(this.url) || this.url.scheme === \"ws\" || this.url.scheme === \"wss\") {\r\n      this.encodingOverride = \"utf-8\";\r\n    }\r\n\r\n    const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead\r\n    for (let i = 0; i < buffer.length; ++i) {\r\n      if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 ||\r\n          buffer[i] === 0x3C || buffer[i] === 0x3E) {\r\n        this.url.query += percentEncode(buffer[i]);\r\n      } else {\r\n        this.url.query += String.fromCodePoint(buffer[i]);\r\n      }\r\n    }\r\n\r\n    this.buffer = \"\";\r\n    if (c === 35) {\r\n      this.url.fragment = \"\";\r\n      this.state = \"fragment\";\r\n    }\r\n  } else {\r\n    // TODO: If c is not a URL code point and not \"%\", parse error.\r\n    if (c === 37 &&\r\n      (!isASCIIHex(this.input[this.pointer + 1]) ||\r\n        !isASCIIHex(this.input[this.pointer + 2]))) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    this.buffer += cStr;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nURLStateMachine.prototype[\"parse fragment\"] = function parseFragment(c) {\r\n  if (isNaN(c)) { // do nothing\r\n  } else if (c === 0x0) {\r\n    this.parseError = true;\r\n  } else {\r\n    // TODO: If c is not a URL code point and not \"%\", parse error.\r\n    if (c === 37 &&\r\n      (!isASCIIHex(this.input[this.pointer + 1]) ||\r\n        !isASCIIHex(this.input[this.pointer + 2]))) {\r\n      this.parseError = true;\r\n    }\r\n\r\n    this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode);\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nfunction serializeURL(url, excludeFragment) {\r\n  let output = url.scheme + \":\";\r\n  if (url.host !== null) {\r\n    output += \"//\";\r\n\r\n    if (url.username !== \"\" || url.password !== \"\") {\r\n      output += url.username;\r\n      if (url.password !== \"\") {\r\n        output += \":\" + url.password;\r\n      }\r\n      output += \"@\";\r\n    }\r\n\r\n    output += serializeHost(url.host);\r\n\r\n    if (url.port !== null) {\r\n      output += \":\" + url.port;\r\n    }\r\n  } else if (url.host === null && url.scheme === \"file\") {\r\n    output += \"//\";\r\n  }\r\n\r\n  if (url.cannotBeABaseURL) {\r\n    output += url.path[0];\r\n  } else {\r\n    for (const string of url.path) {\r\n      output += \"/\" + string;\r\n    }\r\n  }\r\n\r\n  if (url.query !== null) {\r\n    output += \"?\" + url.query;\r\n  }\r\n\r\n  if (!excludeFragment && url.fragment !== null) {\r\n    output += \"#\" + url.fragment;\r\n  }\r\n\r\n  return output;\r\n}\r\n\r\nfunction serializeOrigin(tuple) {\r\n  let result = tuple.scheme + \"://\";\r\n  result += serializeHost(tuple.host);\r\n\r\n  if (tuple.port !== null) {\r\n    result += \":\" + tuple.port;\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\nmodule.exports.serializeURL = serializeURL;\r\n\r\nmodule.exports.serializeURLOrigin = function (url) {\r\n  // https://url.spec.whatwg.org/#concept-url-origin\r\n  switch (url.scheme) {\r\n    case \"blob\":\r\n      try {\r\n        return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0]));\r\n      } catch (e) {\r\n        // serializing an opaque origin returns \"null\"\r\n        return \"null\";\r\n      }\r\n    case \"ftp\":\r\n    case \"gopher\":\r\n    case \"http\":\r\n    case \"https\":\r\n    case \"ws\":\r\n    case \"wss\":\r\n      return serializeOrigin({\r\n        scheme: url.scheme,\r\n        host: url.host,\r\n        port: url.port\r\n      });\r\n    case \"file\":\r\n      // spec says \"exercise to the reader\", chrome says \"file://\"\r\n      return \"file://\";\r\n    default:\r\n      // serializing an opaque origin returns \"null\"\r\n      return \"null\";\r\n  }\r\n};\r\n\r\nmodule.exports.basicURLParse = function (input, options) {\r\n  if (options === undefined) {\r\n    options = {};\r\n  }\r\n\r\n  const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride);\r\n  if (usm.failure) {\r\n    return \"failure\";\r\n  }\r\n\r\n  return usm.url;\r\n};\r\n\r\nmodule.exports.setTheUsername = function (url, username) {\r\n  url.username = \"\";\r\n  const decoded = punycode.ucs2.decode(username);\r\n  for (let i = 0; i < decoded.length; ++i) {\r\n    url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode);\r\n  }\r\n};\r\n\r\nmodule.exports.setThePassword = function (url, password) {\r\n  url.password = \"\";\r\n  const decoded = punycode.ucs2.decode(password);\r\n  for (let i = 0; i < decoded.length; ++i) {\r\n    url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode);\r\n  }\r\n};\r\n\r\nmodule.exports.serializeHost = serializeHost;\r\n\r\nmodule.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort;\r\n\r\nmodule.exports.serializeInteger = function (integer) {\r\n  return String(integer);\r\n};\r\n\r\nmodule.exports.parseURL = function (input, options) {\r\n  if (options === undefined) {\r\n    options = {};\r\n  }\r\n\r\n  // We don't handle blobs, so this just delegates:\r\n  return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride });\r\n};\r\n\n\n/***/ }),\n\n/***/ 3185:\n/***/ ((module) => {\n\n\"use strict\";\n\n\nmodule.exports.mixin = function mixin(target, source) {\n  const keys = Object.getOwnPropertyNames(source);\n  for (let i = 0; i < keys.length; ++i) {\n    Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i]));\n  }\n};\n\nmodule.exports.wrapperSymbol = Symbol(\"wrapper\");\nmodule.exports.implSymbol = Symbol(\"impl\");\n\nmodule.exports.wrapperForImpl = function (impl) {\n  return impl[module.exports.wrapperSymbol];\n};\n\nmodule.exports.implForWrapper = function (wrapper) {\n  return wrapper[module.exports.implSymbol];\n};\n\n\n\n/***/ }),\n\n/***/ 2940:\n/***/ ((module) => {\n\n// Returns a wrapper function that returns a wrapped callback\n// The wrapper function should do some stuff, and return a\n// presumably different callback function.\n// This makes sure that own properties are retained, so that\n// decorations and such are not lost along the way.\nmodule.exports = wrappy\nfunction wrappy (fn, cb) {\n  if (fn && cb) return wrappy(fn)(cb)\n\n  if (typeof fn !== 'function')\n    throw new TypeError('need wrapper function')\n\n  Object.keys(fn).forEach(function (k) {\n    wrapper[k] = fn[k]\n  })\n\n  return wrapper\n\n  function wrapper() {\n    var args = new Array(arguments.length)\n    for (var i = 0; i < args.length; i++) {\n      args[i] = arguments[i]\n    }\n    var ret = fn.apply(this, args)\n    var cb = args[args.length-1]\n    if (typeof ret === 'function' && ret !== cb) {\n      Object.keys(cb).forEach(function (k) {\n        ret[k] = cb[k]\n      })\n    }\n    return ret\n  }\n}\n\n\n/***/ }),\n\n/***/ 2877:\n/***/ ((module) => {\n\nmodule.exports = eval(\"require\")(\"encoding\");\n\n\n/***/ }),\n\n/***/ 68:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = JSON.parse(\"[[[0,44],\\\"disallowed_STD3_valid\\\"],[[45,46],\\\"valid\\\"],[[47,47],\\\"disallowed_STD3_valid\\\"],[[48,57],\\\"valid\\\"],[[58,64],\\\"disallowed_STD3_valid\\\"],[[65,65],\\\"mapped\\\",[97]],[[66,66],\\\"mapped\\\",[98]],[[67,67],\\\"mapped\\\",[99]],[[68,68],\\\"mapped\\\",[100]],[[69,69],\\\"mapped\\\",[101]],[[70,70],\\\"mapped\\\",[102]],[[71,71],\\\"mapped\\\",[103]],[[72,72],\\\"mapped\\\",[104]],[[73,73],\\\"mapped\\\",[105]],[[74,74],\\\"mapped\\\",[106]],[[75,75],\\\"mapped\\\",[107]],[[76,76],\\\"mapped\\\",[108]],[[77,77],\\\"mapped\\\",[109]],[[78,78],\\\"mapped\\\",[110]],[[79,79],\\\"mapped\\\",[111]],[[80,80],\\\"mapped\\\",[112]],[[81,81],\\\"mapped\\\",[113]],[[82,82],\\\"mapped\\\",[114]],[[83,83],\\\"mapped\\\",[115]],[[84,84],\\\"mapped\\\",[116]],[[85,85],\\\"mapped\\\",[117]],[[86,86],\\\"mapped\\\",[118]],[[87,87],\\\"mapped\\\",[119]],[[88,88],\\\"mapped\\\",[120]],[[89,89],\\\"mapped\\\",[121]],[[90,90],\\\"mapped\\\",[122]],[[91,96],\\\"disallowed_STD3_valid\\\"],[[97,122],\\\"valid\\\"],[[123,127],\\\"disallowed_STD3_valid\\\"],[[128,159],\\\"disallowed\\\"],[[160,160],\\\"disallowed_STD3_mapped\\\",[32]],[[161,167],\\\"valid\\\",[],\\\"NV8\\\"],[[168,168],\\\"disallowed_STD3_mapped\\\",[32,776]],[[169,169],\\\"valid\\\",[],\\\"NV8\\\"],[[170,170],\\\"mapped\\\",[97]],[[171,172],\\\"valid\\\",[],\\\"NV8\\\"],[[173,173],\\\"ignored\\\"],[[174,174],\\\"valid\\\",[],\\\"NV8\\\"],[[175,175],\\\"disallowed_STD3_mapped\\\",[32,772]],[[176,177],\\\"valid\\\",[],\\\"NV8\\\"],[[178,178],\\\"mapped\\\",[50]],[[179,179],\\\"mapped\\\",[51]],[[180,180],\\\"disallowed_STD3_mapped\\\",[32,769]],[[181,181],\\\"mapped\\\",[956]],[[182,182],\\\"valid\\\",[],\\\"NV8\\\"],[[183,183],\\\"valid\\\"],[[184,184],\\\"disallowed_STD3_mapped\\\",[32,807]],[[185,185],\\\"mapped\\\",[49]],[[186,186],\\\"mapped\\\",[111]],[[187,187],\\\"valid\\\",[],\\\"NV8\\\"],[[188,188],\\\"mapped\\\",[49,8260,52]],[[189,189],\\\"mapped\\\",[49,8260,50]],[[190,190],\\\"mapped\\\",[51,8260,52]],[[191,191],\\\"valid\\\",[],\\\"NV8\\\"],[[192,192],\\\"mapped\\\",[224]],[[193,193],\\\"mapped\\\",[225]],[[194,194],\\\"mapped\\\",[226]],[[195,195],\\\"mapped\\\",[227]],[[196,196],\\\"mapped\\\",[228]],[[197,197],\\\"mapped\\\",[229]],[[198,198],\\\"mapped\\\",[230]],[[199,199],\\\"mapped\\\",[231]],[[200,200],\\\"mapped\\\",[232]],[[201,201],\\\"mapped\\\",[233]],[[202,202],\\\"mapped\\\",[234]],[[203,203],\\\"mapped\\\",[235]],[[204,204],\\\"mapped\\\",[236]],[[205,205],\\\"mapped\\\",[237]],[[206,206],\\\"mapped\\\",[238]],[[207,207],\\\"mapped\\\",[239]],[[208,208],\\\"mapped\\\",[240]],[[209,209],\\\"mapped\\\",[241]],[[210,210],\\\"mapped\\\",[242]],[[211,211],\\\"mapped\\\",[243]],[[212,212],\\\"mapped\\\",[244]],[[213,213],\\\"mapped\\\",[245]],[[214,214],\\\"mapped\\\",[246]],[[215,215],\\\"valid\\\",[],\\\"NV8\\\"],[[216,216],\\\"mapped\\\",[248]],[[217,217],\\\"mapped\\\",[249]],[[218,218],\\\"mapped\\\",[250]],[[219,219],\\\"mapped\\\",[251]],[[220,220],\\\"mapped\\\",[252]],[[221,221],\\\"mapped\\\",[253]],[[222,222],\\\"mapped\\\",[254]],[[223,223],\\\"deviation\\\",[115,115]],[[224,246],\\\"valid\\\"],[[247,247],\\\"valid\\\",[],\\\"NV8\\\"],[[248,255],\\\"valid\\\"],[[256,256],\\\"mapped\\\",[257]],[[257,257],\\\"valid\\\"],[[258,258],\\\"mapped\\\",[259]],[[259,259],\\\"valid\\\"],[[260,260],\\\"mapped\\\",[261]],[[261,261],\\\"valid\\\"],[[262,262],\\\"mapped\\\",[263]],[[263,263],\\\"valid\\\"],[[264,264],\\\"mapped\\\",[265]],[[265,265],\\\"valid\\\"],[[266,266],\\\"mapped\\\",[267]],[[267,267],\\\"valid\\\"],[[268,268],\\\"mapped\\\",[269]],[[269,269],\\\"valid\\\"],[[270,270],\\\"mapped\\\",[271]],[[271,271],\\\"valid\\\"],[[272,272],\\\"mapped\\\",[273]],[[273,273],\\\"valid\\\"],[[274,274],\\\"mapped\\\",[275]],[[275,275],\\\"valid\\\"],[[276,276],\\\"mapped\\\",[277]],[[277,277],\\\"valid\\\"],[[278,278],\\\"mapped\\\",[279]],[[279,279],\\\"valid\\\"],[[280,280],\\\"mapped\\\",[281]],[[281,281],\\\"valid\\\"],[[282,282],\\\"mapped\\\",[283]],[[283,283],\\\"valid\\\"],[[284,284],\\\"mapped\\\",[285]],[[285,285],\\\"valid\\\"],[[286,286],\\\"mapped\\\",[287]],[[287,287],\\\"valid\\\"],[[288,288],\\\"mapped\\\",[289]],[[289,289],\\\"valid\\\"],[[290,290],\\\"mapped\\\",[291]],[[291,291],\\\"valid\\\"],[[292,292],\\\"mapped\\\",[293]],[[293,293],\\\"valid\\\"],[[294,294],\\\"mapped\\\",[295]],[[295,295],\\\"valid\\\"],[[296,296],\\\"mapped\\\",[297]],[[297,297],\\\"valid\\\"],[[298,298],\\\"mapped\\\",[299]],[[299,299],\\\"valid\\\"],[[300,300],\\\"mapped\\\",[301]],[[301,301],\\\"valid\\\"],[[302,302],\\\"mapped\\\",[303]],[[303,303],\\\"valid\\\"],[[304,304],\\\"mapped\\\",[105,775]],[[305,305],\\\"valid\\\"],[[306,307],\\\"mapped\\\",[105,106]],[[308,308],\\\"mapped\\\",[309]],[[309,309],\\\"valid\\\"],[[310,310],\\\"mapped\\\",[311]],[[311,312],\\\"valid\\\"],[[313,313],\\\"mapped\\\",[314]],[[314,314],\\\"valid\\\"],[[315,315],\\\"mapped\\\",[316]],[[316,316],\\\"valid\\\"],[[317,317],\\\"mapped\\\",[318]],[[318,318],\\\"valid\\\"],[[319,320],\\\"mapped\\\",[108,183]],[[321,321],\\\"mapped\\\",[322]],[[322,322],\\\"valid\\\"],[[323,323],\\\"mapped\\\",[324]],[[324,324],\\\"valid\\\"],[[325,325],\\\"mapped\\\",[326]],[[326,326],\\\"valid\\\"],[[327,327],\\\"mapped\\\",[328]],[[328,328],\\\"valid\\\"],[[329,329],\\\"mapped\\\",[700,110]],[[330,330],\\\"mapped\\\",[331]],[[331,331],\\\"valid\\\"],[[332,332],\\\"mapped\\\",[333]],[[333,333],\\\"valid\\\"],[[334,334],\\\"mapped\\\",[335]],[[335,335],\\\"valid\\\"],[[336,336],\\\"mapped\\\",[337]],[[337,337],\\\"valid\\\"],[[338,338],\\\"mapped\\\",[339]],[[339,339],\\\"valid\\\"],[[340,340],\\\"mapped\\\",[341]],[[341,341],\\\"valid\\\"],[[342,342],\\\"mapped\\\",[343]],[[343,343],\\\"valid\\\"],[[344,344],\\\"mapped\\\",[345]],[[345,345],\\\"valid\\\"],[[346,346],\\\"mapped\\\",[347]],[[347,347],\\\"valid\\\"],[[348,348],\\\"mapped\\\",[349]],[[349,349],\\\"valid\\\"],[[350,350],\\\"mapped\\\",[351]],[[351,351],\\\"valid\\\"],[[352,352],\\\"mapped\\\",[353]],[[353,353],\\\"valid\\\"],[[354,354],\\\"mapped\\\",[355]],[[355,355],\\\"valid\\\"],[[356,356],\\\"mapped\\\",[357]],[[357,357],\\\"valid\\\"],[[358,358],\\\"mapped\\\",[359]],[[359,359],\\\"valid\\\"],[[360,360],\\\"mapped\\\",[361]],[[361,361],\\\"valid\\\"],[[362,362],\\\"mapped\\\",[363]],[[363,363],\\\"valid\\\"],[[364,364],\\\"mapped\\\",[365]],[[365,365],\\\"valid\\\"],[[366,366],\\\"mapped\\\",[367]],[[367,367],\\\"valid\\\"],[[368,368],\\\"mapped\\\",[369]],[[369,369],\\\"valid\\\"],[[370,370],\\\"mapped\\\",[371]],[[371,371],\\\"valid\\\"],[[372,372],\\\"mapped\\\",[373]],[[373,373],\\\"valid\\\"],[[374,374],\\\"mapped\\\",[375]],[[375,375],\\\"valid\\\"],[[376,376],\\\"mapped\\\",[255]],[[377,377],\\\"mapped\\\",[378]],[[378,378],\\\"valid\\\"],[[379,379],\\\"mapped\\\",[380]],[[380,380],\\\"valid\\\"],[[381,381],\\\"mapped\\\",[382]],[[382,382],\\\"valid\\\"],[[383,383],\\\"mapped\\\",[115]],[[384,384],\\\"valid\\\"],[[385,385],\\\"mapped\\\",[595]],[[386,386],\\\"mapped\\\",[387]],[[387,387],\\\"valid\\\"],[[388,388],\\\"mapped\\\",[389]],[[389,389],\\\"valid\\\"],[[390,390],\\\"mapped\\\",[596]],[[391,391],\\\"mapped\\\",[392]],[[392,392],\\\"valid\\\"],[[393,393],\\\"mapped\\\",[598]],[[394,394],\\\"mapped\\\",[599]],[[395,395],\\\"mapped\\\",[396]],[[396,397],\\\"valid\\\"],[[398,398],\\\"mapped\\\",[477]],[[399,399],\\\"mapped\\\",[601]],[[400,400],\\\"mapped\\\",[603]],[[401,401],\\\"mapped\\\",[402]],[[402,402],\\\"valid\\\"],[[403,403],\\\"mapped\\\",[608]],[[404,404],\\\"mapped\\\",[611]],[[405,405],\\\"valid\\\"],[[406,406],\\\"mapped\\\",[617]],[[407,407],\\\"mapped\\\",[616]],[[408,408],\\\"mapped\\\",[409]],[[409,411],\\\"valid\\\"],[[412,412],\\\"mapped\\\",[623]],[[413,413],\\\"mapped\\\",[626]],[[414,414],\\\"valid\\\"],[[415,415],\\\"mapped\\\",[629]],[[416,416],\\\"mapped\\\",[417]],[[417,417],\\\"valid\\\"],[[418,418],\\\"mapped\\\",[419]],[[419,419],\\\"valid\\\"],[[420,420],\\\"mapped\\\",[421]],[[421,421],\\\"valid\\\"],[[422,422],\\\"mapped\\\",[640]],[[423,423],\\\"mapped\\\",[424]],[[424,424],\\\"valid\\\"],[[425,425],\\\"mapped\\\",[643]],[[426,427],\\\"valid\\\"],[[428,428],\\\"mapped\\\",[429]],[[429,429],\\\"valid\\\"],[[430,430],\\\"mapped\\\",[648]],[[431,431],\\\"mapped\\\",[432]],[[432,432],\\\"valid\\\"],[[433,433],\\\"mapped\\\",[650]],[[434,434],\\\"mapped\\\",[651]],[[435,435],\\\"mapped\\\",[436]],[[436,436],\\\"valid\\\"],[[437,437],\\\"mapped\\\",[438]],[[438,438],\\\"valid\\\"],[[439,439],\\\"mapped\\\",[658]],[[440,440],\\\"mapped\\\",[441]],[[441,443],\\\"valid\\\"],[[444,444],\\\"mapped\\\",[445]],[[445,451],\\\"valid\\\"],[[452,454],\\\"mapped\\\",[100,382]],[[455,457],\\\"mapped\\\",[108,106]],[[458,460],\\\"mapped\\\",[110,106]],[[461,461],\\\"mapped\\\",[462]],[[462,462],\\\"valid\\\"],[[463,463],\\\"mapped\\\",[464]],[[464,464],\\\"valid\\\"],[[465,465],\\\"mapped\\\",[466]],[[466,466],\\\"valid\\\"],[[467,467],\\\"mapped\\\",[468]],[[468,468],\\\"valid\\\"],[[469,469],\\\"mapped\\\",[470]],[[470,470],\\\"valid\\\"],[[471,471],\\\"mapped\\\",[472]],[[472,472],\\\"valid\\\"],[[473,473],\\\"mapped\\\",[474]],[[474,474],\\\"valid\\\"],[[475,475],\\\"mapped\\\",[476]],[[476,477],\\\"valid\\\"],[[478,478],\\\"mapped\\\",[479]],[[479,479],\\\"valid\\\"],[[480,480],\\\"mapped\\\",[481]],[[481,481],\\\"valid\\\"],[[482,482],\\\"mapped\\\",[483]],[[483,483],\\\"valid\\\"],[[484,484],\\\"mapped\\\",[485]],[[485,485],\\\"valid\\\"],[[486,486],\\\"mapped\\\",[487]],[[487,487],\\\"valid\\\"],[[488,488],\\\"mapped\\\",[489]],[[489,489],\\\"valid\\\"],[[490,490],\\\"mapped\\\",[491]],[[491,491],\\\"valid\\\"],[[492,492],\\\"mapped\\\",[493]],[[493,493],\\\"valid\\\"],[[494,494],\\\"mapped\\\",[495]],[[495,496],\\\"valid\\\"],[[497,499],\\\"mapped\\\",[100,122]],[[500,500],\\\"mapped\\\",[501]],[[501,501],\\\"valid\\\"],[[502,502],\\\"mapped\\\",[405]],[[503,503],\\\"mapped\\\",[447]],[[504,504],\\\"mapped\\\",[505]],[[505,505],\\\"valid\\\"],[[506,506],\\\"mapped\\\",[507]],[[507,507],\\\"valid\\\"],[[508,508],\\\"mapped\\\",[509]],[[509,509],\\\"valid\\\"],[[510,510],\\\"mapped\\\",[511]],[[511,511],\\\"valid\\\"],[[512,512],\\\"mapped\\\",[513]],[[513,513],\\\"valid\\\"],[[514,514],\\\"mapped\\\",[515]],[[515,515],\\\"valid\\\"],[[516,516],\\\"mapped\\\",[517]],[[517,517],\\\"valid\\\"],[[518,518],\\\"mapped\\\",[519]],[[519,519],\\\"valid\\\"],[[520,520],\\\"mapped\\\",[521]],[[521,521],\\\"valid\\\"],[[522,522],\\\"mapped\\\",[523]],[[523,523],\\\"valid\\\"],[[524,524],\\\"mapped\\\",[525]],[[525,525],\\\"valid\\\"],[[526,526],\\\"mapped\\\",[527]],[[527,527],\\\"valid\\\"],[[528,528],\\\"mapped\\\",[529]],[[529,529],\\\"valid\\\"],[[530,530],\\\"mapped\\\",[531]],[[531,531],\\\"valid\\\"],[[532,532],\\\"mapped\\\",[533]],[[533,533],\\\"valid\\\"],[[534,534],\\\"mapped\\\",[535]],[[535,535],\\\"valid\\\"],[[536,536],\\\"mapped\\\",[537]],[[537,537],\\\"valid\\\"],[[538,538],\\\"mapped\\\",[539]],[[539,539],\\\"valid\\\"],[[540,540],\\\"mapped\\\",[541]],[[541,541],\\\"valid\\\"],[[542,542],\\\"mapped\\\",[543]],[[543,543],\\\"valid\\\"],[[544,544],\\\"mapped\\\",[414]],[[545,545],\\\"valid\\\"],[[546,546],\\\"mapped\\\",[547]],[[547,547],\\\"valid\\\"],[[548,548],\\\"mapped\\\",[549]],[[549,549],\\\"valid\\\"],[[550,550],\\\"mapped\\\",[551]],[[551,551],\\\"valid\\\"],[[552,552],\\\"mapped\\\",[553]],[[553,553],\\\"valid\\\"],[[554,554],\\\"mapped\\\",[555]],[[555,555],\\\"valid\\\"],[[556,556],\\\"mapped\\\",[557]],[[557,557],\\\"valid\\\"],[[558,558],\\\"mapped\\\",[559]],[[559,559],\\\"valid\\\"],[[560,560],\\\"mapped\\\",[561]],[[561,561],\\\"valid\\\"],[[562,562],\\\"mapped\\\",[563]],[[563,563],\\\"valid\\\"],[[564,566],\\\"valid\\\"],[[567,569],\\\"valid\\\"],[[570,570],\\\"mapped\\\",[11365]],[[571,571],\\\"mapped\\\",[572]],[[572,572],\\\"valid\\\"],[[573,573],\\\"mapped\\\",[410]],[[574,574],\\\"mapped\\\",[11366]],[[575,576],\\\"valid\\\"],[[577,577],\\\"mapped\\\",[578]],[[578,578],\\\"valid\\\"],[[579,579],\\\"mapped\\\",[384]],[[580,580],\\\"mapped\\\",[649]],[[581,581],\\\"mapped\\\",[652]],[[582,582],\\\"mapped\\\",[583]],[[583,583],\\\"valid\\\"],[[584,584],\\\"mapped\\\",[585]],[[585,585],\\\"valid\\\"],[[586,586],\\\"mapped\\\",[587]],[[587,587],\\\"valid\\\"],[[588,588],\\\"mapped\\\",[589]],[[589,589],\\\"valid\\\"],[[590,590],\\\"mapped\\\",[591]],[[591,591],\\\"valid\\\"],[[592,680],\\\"valid\\\"],[[681,685],\\\"valid\\\"],[[686,687],\\\"valid\\\"],[[688,688],\\\"mapped\\\",[104]],[[689,689],\\\"mapped\\\",[614]],[[690,690],\\\"mapped\\\",[106]],[[691,691],\\\"mapped\\\",[114]],[[692,692],\\\"mapped\\\",[633]],[[693,693],\\\"mapped\\\",[635]],[[694,694],\\\"mapped\\\",[641]],[[695,695],\\\"mapped\\\",[119]],[[696,696],\\\"mapped\\\",[121]],[[697,705],\\\"valid\\\"],[[706,709],\\\"valid\\\",[],\\\"NV8\\\"],[[710,721],\\\"valid\\\"],[[722,727],\\\"valid\\\",[],\\\"NV8\\\"],[[728,728],\\\"disallowed_STD3_mapped\\\",[32,774]],[[729,729],\\\"disallowed_STD3_mapped\\\",[32,775]],[[730,730],\\\"disallowed_STD3_mapped\\\",[32,778]],[[731,731],\\\"disallowed_STD3_mapped\\\",[32,808]],[[732,732],\\\"disallowed_STD3_mapped\\\",[32,771]],[[733,733],\\\"disallowed_STD3_mapped\\\",[32,779]],[[734,734],\\\"valid\\\",[],\\\"NV8\\\"],[[735,735],\\\"valid\\\",[],\\\"NV8\\\"],[[736,736],\\\"mapped\\\",[611]],[[737,737],\\\"mapped\\\",[108]],[[738,738],\\\"mapped\\\",[115]],[[739,739],\\\"mapped\\\",[120]],[[740,740],\\\"mapped\\\",[661]],[[741,745],\\\"valid\\\",[],\\\"NV8\\\"],[[746,747],\\\"valid\\\",[],\\\"NV8\\\"],[[748,748],\\\"valid\\\"],[[749,749],\\\"valid\\\",[],\\\"NV8\\\"],[[750,750],\\\"valid\\\"],[[751,767],\\\"valid\\\",[],\\\"NV8\\\"],[[768,831],\\\"valid\\\"],[[832,832],\\\"mapped\\\",[768]],[[833,833],\\\"mapped\\\",[769]],[[834,834],\\\"valid\\\"],[[835,835],\\\"mapped\\\",[787]],[[836,836],\\\"mapped\\\",[776,769]],[[837,837],\\\"mapped\\\",[953]],[[838,846],\\\"valid\\\"],[[847,847],\\\"ignored\\\"],[[848,855],\\\"valid\\\"],[[856,860],\\\"valid\\\"],[[861,863],\\\"valid\\\"],[[864,865],\\\"valid\\\"],[[866,866],\\\"valid\\\"],[[867,879],\\\"valid\\\"],[[880,880],\\\"mapped\\\",[881]],[[881,881],\\\"valid\\\"],[[882,882],\\\"mapped\\\",[883]],[[883,883],\\\"valid\\\"],[[884,884],\\\"mapped\\\",[697]],[[885,885],\\\"valid\\\"],[[886,886],\\\"mapped\\\",[887]],[[887,887],\\\"valid\\\"],[[888,889],\\\"disallowed\\\"],[[890,890],\\\"disallowed_STD3_mapped\\\",[32,953]],[[891,893],\\\"valid\\\"],[[894,894],\\\"disallowed_STD3_mapped\\\",[59]],[[895,895],\\\"mapped\\\",[1011]],[[896,899],\\\"disallowed\\\"],[[900,900],\\\"disallowed_STD3_mapped\\\",[32,769]],[[901,901],\\\"disallowed_STD3_mapped\\\",[32,776,769]],[[902,902],\\\"mapped\\\",[940]],[[903,903],\\\"mapped\\\",[183]],[[904,904],\\\"mapped\\\",[941]],[[905,905],\\\"mapped\\\",[942]],[[906,906],\\\"mapped\\\",[943]],[[907,907],\\\"disallowed\\\"],[[908,908],\\\"mapped\\\",[972]],[[909,909],\\\"disallowed\\\"],[[910,910],\\\"mapped\\\",[973]],[[911,911],\\\"mapped\\\",[974]],[[912,912],\\\"valid\\\"],[[913,913],\\\"mapped\\\",[945]],[[914,914],\\\"mapped\\\",[946]],[[915,915],\\\"mapped\\\",[947]],[[916,916],\\\"mapped\\\",[948]],[[917,917],\\\"mapped\\\",[949]],[[918,918],\\\"mapped\\\",[950]],[[919,919],\\\"mapped\\\",[951]],[[920,920],\\\"mapped\\\",[952]],[[921,921],\\\"mapped\\\",[953]],[[922,922],\\\"mapped\\\",[954]],[[923,923],\\\"mapped\\\",[955]],[[924,924],\\\"mapped\\\",[956]],[[925,925],\\\"mapped\\\",[957]],[[926,926],\\\"mapped\\\",[958]],[[927,927],\\\"mapped\\\",[959]],[[928,928],\\\"mapped\\\",[960]],[[929,929],\\\"mapped\\\",[961]],[[930,930],\\\"disallowed\\\"],[[931,931],\\\"mapped\\\",[963]],[[932,932],\\\"mapped\\\",[964]],[[933,933],\\\"mapped\\\",[965]],[[934,934],\\\"mapped\\\",[966]],[[935,935],\\\"mapped\\\",[967]],[[936,936],\\\"mapped\\\",[968]],[[937,937],\\\"mapped\\\",[969]],[[938,938],\\\"mapped\\\",[970]],[[939,939],\\\"mapped\\\",[971]],[[940,961],\\\"valid\\\"],[[962,962],\\\"deviation\\\",[963]],[[963,974],\\\"valid\\\"],[[975,975],\\\"mapped\\\",[983]],[[976,976],\\\"mapped\\\",[946]],[[977,977],\\\"mapped\\\",[952]],[[978,978],\\\"mapped\\\",[965]],[[979,979],\\\"mapped\\\",[973]],[[980,980],\\\"mapped\\\",[971]],[[981,981],\\\"mapped\\\",[966]],[[982,982],\\\"mapped\\\",[960]],[[983,983],\\\"valid\\\"],[[984,984],\\\"mapped\\\",[985]],[[985,985],\\\"valid\\\"],[[986,986],\\\"mapped\\\",[987]],[[987,987],\\\"valid\\\"],[[988,988],\\\"mapped\\\",[989]],[[989,989],\\\"valid\\\"],[[990,990],\\\"mapped\\\",[991]],[[991,991],\\\"valid\\\"],[[992,992],\\\"mapped\\\",[993]],[[993,993],\\\"valid\\\"],[[994,994],\\\"mapped\\\",[995]],[[995,995],\\\"valid\\\"],[[996,996],\\\"mapped\\\",[997]],[[997,997],\\\"valid\\\"],[[998,998],\\\"mapped\\\",[999]],[[999,999],\\\"valid\\\"],[[1000,1000],\\\"mapped\\\",[1001]],[[1001,1001],\\\"valid\\\"],[[1002,1002],\\\"mapped\\\",[1003]],[[1003,1003],\\\"valid\\\"],[[1004,1004],\\\"mapped\\\",[1005]],[[1005,1005],\\\"valid\\\"],[[1006,1006],\\\"mapped\\\",[1007]],[[1007,1007],\\\"valid\\\"],[[1008,1008],\\\"mapped\\\",[954]],[[1009,1009],\\\"mapped\\\",[961]],[[1010,1010],\\\"mapped\\\",[963]],[[1011,1011],\\\"valid\\\"],[[1012,1012],\\\"mapped\\\",[952]],[[1013,1013],\\\"mapped\\\",[949]],[[1014,1014],\\\"valid\\\",[],\\\"NV8\\\"],[[1015,1015],\\\"mapped\\\",[1016]],[[1016,1016],\\\"valid\\\"],[[1017,1017],\\\"mapped\\\",[963]],[[1018,1018],\\\"mapped\\\",[1019]],[[1019,1019],\\\"valid\\\"],[[1020,1020],\\\"valid\\\"],[[1021,1021],\\\"mapped\\\",[891]],[[1022,1022],\\\"mapped\\\",[892]],[[1023,1023],\\\"mapped\\\",[893]],[[1024,1024],\\\"mapped\\\",[1104]],[[1025,1025],\\\"mapped\\\",[1105]],[[1026,1026],\\\"mapped\\\",[1106]],[[1027,1027],\\\"mapped\\\",[1107]],[[1028,1028],\\\"mapped\\\",[1108]],[[1029,1029],\\\"mapped\\\",[1109]],[[1030,1030],\\\"mapped\\\",[1110]],[[1031,1031],\\\"mapped\\\",[1111]],[[1032,1032],\\\"mapped\\\",[1112]],[[1033,1033],\\\"mapped\\\",[1113]],[[1034,1034],\\\"mapped\\\",[1114]],[[1035,1035],\\\"mapped\\\",[1115]],[[1036,1036],\\\"mapped\\\",[1116]],[[1037,1037],\\\"mapped\\\",[1117]],[[1038,1038],\\\"mapped\\\",[1118]],[[1039,1039],\\\"mapped\\\",[1119]],[[1040,1040],\\\"mapped\\\",[1072]],[[1041,1041],\\\"mapped\\\",[1073]],[[1042,1042],\\\"mapped\\\",[1074]],[[1043,1043],\\\"mapped\\\",[1075]],[[1044,1044],\\\"mapped\\\",[1076]],[[1045,1045],\\\"mapped\\\",[1077]],[[1046,1046],\\\"mapped\\\",[1078]],[[1047,1047],\\\"mapped\\\",[1079]],[[1048,1048],\\\"mapped\\\",[1080]],[[1049,1049],\\\"mapped\\\",[1081]],[[1050,1050],\\\"mapped\\\",[1082]],[[1051,1051],\\\"mapped\\\",[1083]],[[1052,1052],\\\"mapped\\\",[1084]],[[1053,1053],\\\"mapped\\\",[1085]],[[1054,1054],\\\"mapped\\\",[1086]],[[1055,1055],\\\"mapped\\\",[1087]],[[1056,1056],\\\"mapped\\\",[1088]],[[1057,1057],\\\"mapped\\\",[1089]],[[1058,1058],\\\"mapped\\\",[1090]],[[1059,1059],\\\"mapped\\\",[1091]],[[1060,1060],\\\"mapped\\\",[1092]],[[1061,1061],\\\"mapped\\\",[1093]],[[1062,1062],\\\"mapped\\\",[1094]],[[1063,1063],\\\"mapped\\\",[1095]],[[1064,1064],\\\"mapped\\\",[1096]],[[1065,1065],\\\"mapped\\\",[1097]],[[1066,1066],\\\"mapped\\\",[1098]],[[1067,1067],\\\"mapped\\\",[1099]],[[1068,1068],\\\"mapped\\\",[1100]],[[1069,1069],\\\"mapped\\\",[1101]],[[1070,1070],\\\"mapped\\\",[1102]],[[1071,1071],\\\"mapped\\\",[1103]],[[1072,1103],\\\"valid\\\"],[[1104,1104],\\\"valid\\\"],[[1105,1116],\\\"valid\\\"],[[1117,1117],\\\"valid\\\"],[[1118,1119],\\\"valid\\\"],[[1120,1120],\\\"mapped\\\",[1121]],[[1121,1121],\\\"valid\\\"],[[1122,1122],\\\"mapped\\\",[1123]],[[1123,1123],\\\"valid\\\"],[[1124,1124],\\\"mapped\\\",[1125]],[[1125,1125],\\\"valid\\\"],[[1126,1126],\\\"mapped\\\",[1127]],[[1127,1127],\\\"valid\\\"],[[1128,1128],\\\"mapped\\\",[1129]],[[1129,1129],\\\"valid\\\"],[[1130,1130],\\\"mapped\\\",[1131]],[[1131,1131],\\\"valid\\\"],[[1132,1132],\\\"mapped\\\",[1133]],[[1133,1133],\\\"valid\\\"],[[1134,1134],\\\"mapped\\\",[1135]],[[1135,1135],\\\"valid\\\"],[[1136,1136],\\\"mapped\\\",[1137]],[[1137,1137],\\\"valid\\\"],[[1138,1138],\\\"mapped\\\",[1139]],[[1139,1139],\\\"valid\\\"],[[1140,1140],\\\"mapped\\\",[1141]],[[1141,1141],\\\"valid\\\"],[[1142,1142],\\\"mapped\\\",[1143]],[[1143,1143],\\\"valid\\\"],[[1144,1144],\\\"mapped\\\",[1145]],[[1145,1145],\\\"valid\\\"],[[1146,1146],\\\"mapped\\\",[1147]],[[1147,1147],\\\"valid\\\"],[[1148,1148],\\\"mapped\\\",[1149]],[[1149,1149],\\\"valid\\\"],[[1150,1150],\\\"mapped\\\",[1151]],[[1151,1151],\\\"valid\\\"],[[1152,1152],\\\"mapped\\\",[1153]],[[1153,1153],\\\"valid\\\"],[[1154,1154],\\\"valid\\\",[],\\\"NV8\\\"],[[1155,1158],\\\"valid\\\"],[[1159,1159],\\\"valid\\\"],[[1160,1161],\\\"valid\\\",[],\\\"NV8\\\"],[[1162,1162],\\\"mapped\\\",[1163]],[[1163,1163],\\\"valid\\\"],[[1164,1164],\\\"mapped\\\",[1165]],[[1165,1165],\\\"valid\\\"],[[1166,1166],\\\"mapped\\\",[1167]],[[1167,1167],\\\"valid\\\"],[[1168,1168],\\\"mapped\\\",[1169]],[[1169,1169],\\\"valid\\\"],[[1170,1170],\\\"mapped\\\",[1171]],[[1171,1171],\\\"valid\\\"],[[1172,1172],\\\"mapped\\\",[1173]],[[1173,1173],\\\"valid\\\"],[[1174,1174],\\\"mapped\\\",[1175]],[[1175,1175],\\\"valid\\\"],[[1176,1176],\\\"mapped\\\",[1177]],[[1177,1177],\\\"valid\\\"],[[1178,1178],\\\"mapped\\\",[1179]],[[1179,1179],\\\"valid\\\"],[[1180,1180],\\\"mapped\\\",[1181]],[[1181,1181],\\\"valid\\\"],[[1182,1182],\\\"mapped\\\",[1183]],[[1183,1183],\\\"valid\\\"],[[1184,1184],\\\"mapped\\\",[1185]],[[1185,1185],\\\"valid\\\"],[[1186,1186],\\\"mapped\\\",[1187]],[[1187,1187],\\\"valid\\\"],[[1188,1188],\\\"mapped\\\",[1189]],[[1189,1189],\\\"valid\\\"],[[1190,1190],\\\"mapped\\\",[1191]],[[1191,1191],\\\"valid\\\"],[[1192,1192],\\\"mapped\\\",[1193]],[[1193,1193],\\\"valid\\\"],[[1194,1194],\\\"mapped\\\",[1195]],[[1195,1195],\\\"valid\\\"],[[1196,1196],\\\"mapped\\\",[1197]],[[1197,1197],\\\"valid\\\"],[[1198,1198],\\\"mapped\\\",[1199]],[[1199,1199],\\\"valid\\\"],[[1200,1200],\\\"mapped\\\",[1201]],[[1201,1201],\\\"valid\\\"],[[1202,1202],\\\"mapped\\\",[1203]],[[1203,1203],\\\"valid\\\"],[[1204,1204],\\\"mapped\\\",[1205]],[[1205,1205],\\\"valid\\\"],[[1206,1206],\\\"mapped\\\",[1207]],[[1207,1207],\\\"valid\\\"],[[1208,1208],\\\"mapped\\\",[1209]],[[1209,1209],\\\"valid\\\"],[[1210,1210],\\\"mapped\\\",[1211]],[[1211,1211],\\\"valid\\\"],[[1212,1212],\\\"mapped\\\",[1213]],[[1213,1213],\\\"valid\\\"],[[1214,1214],\\\"mapped\\\",[1215]],[[1215,1215],\\\"valid\\\"],[[1216,1216],\\\"disallowed\\\"],[[1217,1217],\\\"mapped\\\",[1218]],[[1218,1218],\\\"valid\\\"],[[1219,1219],\\\"mapped\\\",[1220]],[[1220,1220],\\\"valid\\\"],[[1221,1221],\\\"mapped\\\",[1222]],[[1222,1222],\\\"valid\\\"],[[1223,1223],\\\"mapped\\\",[1224]],[[1224,1224],\\\"valid\\\"],[[1225,1225],\\\"mapped\\\",[1226]],[[1226,1226],\\\"valid\\\"],[[1227,1227],\\\"mapped\\\",[1228]],[[1228,1228],\\\"valid\\\"],[[1229,1229],\\\"mapped\\\",[1230]],[[1230,1230],\\\"valid\\\"],[[1231,1231],\\\"valid\\\"],[[1232,1232],\\\"mapped\\\",[1233]],[[1233,1233],\\\"valid\\\"],[[1234,1234],\\\"mapped\\\",[1235]],[[1235,1235],\\\"valid\\\"],[[1236,1236],\\\"mapped\\\",[1237]],[[1237,1237],\\\"valid\\\"],[[1238,1238],\\\"mapped\\\",[1239]],[[1239,1239],\\\"valid\\\"],[[1240,1240],\\\"mapped\\\",[1241]],[[1241,1241],\\\"valid\\\"],[[1242,1242],\\\"mapped\\\",[1243]],[[1243,1243],\\\"valid\\\"],[[1244,1244],\\\"mapped\\\",[1245]],[[1245,1245],\\\"valid\\\"],[[1246,1246],\\\"mapped\\\",[1247]],[[1247,1247],\\\"valid\\\"],[[1248,1248],\\\"mapped\\\",[1249]],[[1249,1249],\\\"valid\\\"],[[1250,1250],\\\"mapped\\\",[1251]],[[1251,1251],\\\"valid\\\"],[[1252,1252],\\\"mapped\\\",[1253]],[[1253,1253],\\\"valid\\\"],[[1254,1254],\\\"mapped\\\",[1255]],[[1255,1255],\\\"valid\\\"],[[1256,1256],\\\"mapped\\\",[1257]],[[1257,1257],\\\"valid\\\"],[[1258,1258],\\\"mapped\\\",[1259]],[[1259,1259],\\\"valid\\\"],[[1260,1260],\\\"mapped\\\",[1261]],[[1261,1261],\\\"valid\\\"],[[1262,1262],\\\"mapped\\\",[1263]],[[1263,1263],\\\"valid\\\"],[[1264,1264],\\\"mapped\\\",[1265]],[[1265,1265],\\\"valid\\\"],[[1266,1266],\\\"mapped\\\",[1267]],[[1267,1267],\\\"valid\\\"],[[1268,1268],\\\"mapped\\\",[1269]],[[1269,1269],\\\"valid\\\"],[[1270,1270],\\\"mapped\\\",[1271]],[[1271,1271],\\\"valid\\\"],[[1272,1272],\\\"mapped\\\",[1273]],[[1273,1273],\\\"valid\\\"],[[1274,1274],\\\"mapped\\\",[1275]],[[1275,1275],\\\"valid\\\"],[[1276,1276],\\\"mapped\\\",[1277]],[[1277,1277],\\\"valid\\\"],[[1278,1278],\\\"mapped\\\",[1279]],[[1279,1279],\\\"valid\\\"],[[1280,1280],\\\"mapped\\\",[1281]],[[1281,1281],\\\"valid\\\"],[[1282,1282],\\\"mapped\\\",[1283]],[[1283,1283],\\\"valid\\\"],[[1284,1284],\\\"mapped\\\",[1285]],[[1285,1285],\\\"valid\\\"],[[1286,1286],\\\"mapped\\\",[1287]],[[1287,1287],\\\"valid\\\"],[[1288,1288],\\\"mapped\\\",[1289]],[[1289,1289],\\\"valid\\\"],[[1290,1290],\\\"mapped\\\",[1291]],[[1291,1291],\\\"valid\\\"],[[1292,1292],\\\"mapped\\\",[1293]],[[1293,1293],\\\"valid\\\"],[[1294,1294],\\\"mapped\\\",[1295]],[[1295,1295],\\\"valid\\\"],[[1296,1296],\\\"mapped\\\",[1297]],[[1297,1297],\\\"valid\\\"],[[1298,1298],\\\"mapped\\\",[1299]],[[1299,1299],\\\"valid\\\"],[[1300,1300],\\\"mapped\\\",[1301]],[[1301,1301],\\\"valid\\\"],[[1302,1302],\\\"mapped\\\",[1303]],[[1303,1303],\\\"valid\\\"],[[1304,1304],\\\"mapped\\\",[1305]],[[1305,1305],\\\"valid\\\"],[[1306,1306],\\\"mapped\\\",[1307]],[[1307,1307],\\\"valid\\\"],[[1308,1308],\\\"mapped\\\",[1309]],[[1309,1309],\\\"valid\\\"],[[1310,1310],\\\"mapped\\\",[1311]],[[1311,1311],\\\"valid\\\"],[[1312,1312],\\\"mapped\\\",[1313]],[[1313,1313],\\\"valid\\\"],[[1314,1314],\\\"mapped\\\",[1315]],[[1315,1315],\\\"valid\\\"],[[1316,1316],\\\"mapped\\\",[1317]],[[1317,1317],\\\"valid\\\"],[[1318,1318],\\\"mapped\\\",[1319]],[[1319,1319],\\\"valid\\\"],[[1320,1320],\\\"mapped\\\",[1321]],[[1321,1321],\\\"valid\\\"],[[1322,1322],\\\"mapped\\\",[1323]],[[1323,1323],\\\"valid\\\"],[[1324,1324],\\\"mapped\\\",[1325]],[[1325,1325],\\\"valid\\\"],[[1326,1326],\\\"mapped\\\",[1327]],[[1327,1327],\\\"valid\\\"],[[1328,1328],\\\"disallowed\\\"],[[1329,1329],\\\"mapped\\\",[1377]],[[1330,1330],\\\"mapped\\\",[1378]],[[1331,1331],\\\"mapped\\\",[1379]],[[1332,1332],\\\"mapped\\\",[1380]],[[1333,1333],\\\"mapped\\\",[1381]],[[1334,1334],\\\"mapped\\\",[1382]],[[1335,1335],\\\"mapped\\\",[1383]],[[1336,1336],\\\"mapped\\\",[1384]],[[1337,1337],\\\"mapped\\\",[1385]],[[1338,1338],\\\"mapped\\\",[1386]],[[1339,1339],\\\"mapped\\\",[1387]],[[1340,1340],\\\"mapped\\\",[1388]],[[1341,1341],\\\"mapped\\\",[1389]],[[1342,1342],\\\"mapped\\\",[1390]],[[1343,1343],\\\"mapped\\\",[1391]],[[1344,1344],\\\"mapped\\\",[1392]],[[1345,1345],\\\"mapped\\\",[1393]],[[1346,1346],\\\"mapped\\\",[1394]],[[1347,1347],\\\"mapped\\\",[1395]],[[1348,1348],\\\"mapped\\\",[1396]],[[1349,1349],\\\"mapped\\\",[1397]],[[1350,1350],\\\"mapped\\\",[1398]],[[1351,1351],\\\"mapped\\\",[1399]],[[1352,1352],\\\"mapped\\\",[1400]],[[1353,1353],\\\"mapped\\\",[1401]],[[1354,1354],\\\"mapped\\\",[1402]],[[1355,1355],\\\"mapped\\\",[1403]],[[1356,1356],\\\"mapped\\\",[1404]],[[1357,1357],\\\"mapped\\\",[1405]],[[1358,1358],\\\"mapped\\\",[1406]],[[1359,1359],\\\"mapped\\\",[1407]],[[1360,1360],\\\"mapped\\\",[1408]],[[1361,1361],\\\"mapped\\\",[1409]],[[1362,1362],\\\"mapped\\\",[1410]],[[1363,1363],\\\"mapped\\\",[1411]],[[1364,1364],\\\"mapped\\\",[1412]],[[1365,1365],\\\"mapped\\\",[1413]],[[1366,1366],\\\"mapped\\\",[1414]],[[1367,1368],\\\"disallowed\\\"],[[1369,1369],\\\"valid\\\"],[[1370,1375],\\\"valid\\\",[],\\\"NV8\\\"],[[1376,1376],\\\"disallowed\\\"],[[1377,1414],\\\"valid\\\"],[[1415,1415],\\\"mapped\\\",[1381,1410]],[[1416,1416],\\\"disallowed\\\"],[[1417,1417],\\\"valid\\\",[],\\\"NV8\\\"],[[1418,1418],\\\"valid\\\",[],\\\"NV8\\\"],[[1419,1420],\\\"disallowed\\\"],[[1421,1422],\\\"valid\\\",[],\\\"NV8\\\"],[[1423,1423],\\\"valid\\\",[],\\\"NV8\\\"],[[1424,1424],\\\"disallowed\\\"],[[1425,1441],\\\"valid\\\"],[[1442,1442],\\\"valid\\\"],[[1443,1455],\\\"valid\\\"],[[1456,1465],\\\"valid\\\"],[[1466,1466],\\\"valid\\\"],[[1467,1469],\\\"valid\\\"],[[1470,1470],\\\"valid\\\",[],\\\"NV8\\\"],[[1471,1471],\\\"valid\\\"],[[1472,1472],\\\"valid\\\",[],\\\"NV8\\\"],[[1473,1474],\\\"valid\\\"],[[1475,1475],\\\"valid\\\",[],\\\"NV8\\\"],[[1476,1476],\\\"valid\\\"],[[1477,1477],\\\"valid\\\"],[[1478,1478],\\\"valid\\\",[],\\\"NV8\\\"],[[1479,1479],\\\"valid\\\"],[[1480,1487],\\\"disallowed\\\"],[[1488,1514],\\\"valid\\\"],[[1515,1519],\\\"disallowed\\\"],[[1520,1524],\\\"valid\\\"],[[1525,1535],\\\"disallowed\\\"],[[1536,1539],\\\"disallowed\\\"],[[1540,1540],\\\"disallowed\\\"],[[1541,1541],\\\"disallowed\\\"],[[1542,1546],\\\"valid\\\",[],\\\"NV8\\\"],[[1547,1547],\\\"valid\\\",[],\\\"NV8\\\"],[[1548,1548],\\\"valid\\\",[],\\\"NV8\\\"],[[1549,1551],\\\"valid\\\",[],\\\"NV8\\\"],[[1552,1557],\\\"valid\\\"],[[1558,1562],\\\"valid\\\"],[[1563,1563],\\\"valid\\\",[],\\\"NV8\\\"],[[1564,1564],\\\"disallowed\\\"],[[1565,1565],\\\"disallowed\\\"],[[1566,1566],\\\"valid\\\",[],\\\"NV8\\\"],[[1567,1567],\\\"valid\\\",[],\\\"NV8\\\"],[[1568,1568],\\\"valid\\\"],[[1569,1594],\\\"valid\\\"],[[1595,1599],\\\"valid\\\"],[[1600,1600],\\\"valid\\\",[],\\\"NV8\\\"],[[1601,1618],\\\"valid\\\"],[[1619,1621],\\\"valid\\\"],[[1622,1624],\\\"valid\\\"],[[1625,1630],\\\"valid\\\"],[[1631,1631],\\\"valid\\\"],[[1632,1641],\\\"valid\\\"],[[1642,1645],\\\"valid\\\",[],\\\"NV8\\\"],[[1646,1647],\\\"valid\\\"],[[1648,1652],\\\"valid\\\"],[[1653,1653],\\\"mapped\\\",[1575,1652]],[[1654,1654],\\\"mapped\\\",[1608,1652]],[[1655,1655],\\\"mapped\\\",[1735,1652]],[[1656,1656],\\\"mapped\\\",[1610,1652]],[[1657,1719],\\\"valid\\\"],[[1720,1721],\\\"valid\\\"],[[1722,1726],\\\"valid\\\"],[[1727,1727],\\\"valid\\\"],[[1728,1742],\\\"valid\\\"],[[1743,1743],\\\"valid\\\"],[[1744,1747],\\\"valid\\\"],[[1748,1748],\\\"valid\\\",[],\\\"NV8\\\"],[[1749,1756],\\\"valid\\\"],[[1757,1757],\\\"disallowed\\\"],[[1758,1758],\\\"valid\\\",[],\\\"NV8\\\"],[[1759,1768],\\\"valid\\\"],[[1769,1769],\\\"valid\\\",[],\\\"NV8\\\"],[[1770,1773],\\\"valid\\\"],[[1774,1775],\\\"valid\\\"],[[1776,1785],\\\"valid\\\"],[[1786,1790],\\\"valid\\\"],[[1791,1791],\\\"valid\\\"],[[1792,1805],\\\"valid\\\",[],\\\"NV8\\\"],[[1806,1806],\\\"disallowed\\\"],[[1807,1807],\\\"disallowed\\\"],[[1808,1836],\\\"valid\\\"],[[1837,1839],\\\"valid\\\"],[[1840,1866],\\\"valid\\\"],[[1867,1868],\\\"disallowed\\\"],[[1869,1871],\\\"valid\\\"],[[1872,1901],\\\"valid\\\"],[[1902,1919],\\\"valid\\\"],[[1920,1968],\\\"valid\\\"],[[1969,1969],\\\"valid\\\"],[[1970,1983],\\\"disallowed\\\"],[[1984,2037],\\\"valid\\\"],[[2038,2042],\\\"valid\\\",[],\\\"NV8\\\"],[[2043,2047],\\\"disallowed\\\"],[[2048,2093],\\\"valid\\\"],[[2094,2095],\\\"disallowed\\\"],[[2096,2110],\\\"valid\\\",[],\\\"NV8\\\"],[[2111,2111],\\\"disallowed\\\"],[[2112,2139],\\\"valid\\\"],[[2140,2141],\\\"disallowed\\\"],[[2142,2142],\\\"valid\\\",[],\\\"NV8\\\"],[[2143,2207],\\\"disallowed\\\"],[[2208,2208],\\\"valid\\\"],[[2209,2209],\\\"valid\\\"],[[2210,2220],\\\"valid\\\"],[[2221,2226],\\\"valid\\\"],[[2227,2228],\\\"valid\\\"],[[2229,2274],\\\"disallowed\\\"],[[2275,2275],\\\"valid\\\"],[[2276,2302],\\\"valid\\\"],[[2303,2303],\\\"valid\\\"],[[2304,2304],\\\"valid\\\"],[[2305,2307],\\\"valid\\\"],[[2308,2308],\\\"valid\\\"],[[2309,2361],\\\"valid\\\"],[[2362,2363],\\\"valid\\\"],[[2364,2381],\\\"valid\\\"],[[2382,2382],\\\"valid\\\"],[[2383,2383],\\\"valid\\\"],[[2384,2388],\\\"valid\\\"],[[2389,2389],\\\"valid\\\"],[[2390,2391],\\\"valid\\\"],[[2392,2392],\\\"mapped\\\",[2325,2364]],[[2393,2393],\\\"mapped\\\",[2326,2364]],[[2394,2394],\\\"mapped\\\",[2327,2364]],[[2395,2395],\\\"mapped\\\",[2332,2364]],[[2396,2396],\\\"mapped\\\",[2337,2364]],[[2397,2397],\\\"mapped\\\",[2338,2364]],[[2398,2398],\\\"mapped\\\",[2347,2364]],[[2399,2399],\\\"mapped\\\",[2351,2364]],[[2400,2403],\\\"valid\\\"],[[2404,2405],\\\"valid\\\",[],\\\"NV8\\\"],[[2406,2415],\\\"valid\\\"],[[2416,2416],\\\"valid\\\",[],\\\"NV8\\\"],[[2417,2418],\\\"valid\\\"],[[2419,2423],\\\"valid\\\"],[[2424,2424],\\\"valid\\\"],[[2425,2426],\\\"valid\\\"],[[2427,2428],\\\"valid\\\"],[[2429,2429],\\\"valid\\\"],[[2430,2431],\\\"valid\\\"],[[2432,2432],\\\"valid\\\"],[[2433,2435],\\\"valid\\\"],[[2436,2436],\\\"disallowed\\\"],[[2437,2444],\\\"valid\\\"],[[2445,2446],\\\"disallowed\\\"],[[2447,2448],\\\"valid\\\"],[[2449,2450],\\\"disallowed\\\"],[[2451,2472],\\\"valid\\\"],[[2473,2473],\\\"disallowed\\\"],[[2474,2480],\\\"valid\\\"],[[2481,2481],\\\"disallowed\\\"],[[2482,2482],\\\"valid\\\"],[[2483,2485],\\\"disallowed\\\"],[[2486,2489],\\\"valid\\\"],[[2490,2491],\\\"disallowed\\\"],[[2492,2492],\\\"valid\\\"],[[2493,2493],\\\"valid\\\"],[[2494,2500],\\\"valid\\\"],[[2501,2502],\\\"disallowed\\\"],[[2503,2504],\\\"valid\\\"],[[2505,2506],\\\"disallowed\\\"],[[2507,2509],\\\"valid\\\"],[[2510,2510],\\\"valid\\\"],[[2511,2518],\\\"disallowed\\\"],[[2519,2519],\\\"valid\\\"],[[2520,2523],\\\"disallowed\\\"],[[2524,2524],\\\"mapped\\\",[2465,2492]],[[2525,2525],\\\"mapped\\\",[2466,2492]],[[2526,2526],\\\"disallowed\\\"],[[2527,2527],\\\"mapped\\\",[2479,2492]],[[2528,2531],\\\"valid\\\"],[[2532,2533],\\\"disallowed\\\"],[[2534,2545],\\\"valid\\\"],[[2546,2554],\\\"valid\\\",[],\\\"NV8\\\"],[[2555,2555],\\\"valid\\\",[],\\\"NV8\\\"],[[2556,2560],\\\"disallowed\\\"],[[2561,2561],\\\"valid\\\"],[[2562,2562],\\\"valid\\\"],[[2563,2563],\\\"valid\\\"],[[2564,2564],\\\"disallowed\\\"],[[2565,2570],\\\"valid\\\"],[[2571,2574],\\\"disallowed\\\"],[[2575,2576],\\\"valid\\\"],[[2577,2578],\\\"disallowed\\\"],[[2579,2600],\\\"valid\\\"],[[2601,2601],\\\"disallowed\\\"],[[2602,2608],\\\"valid\\\"],[[2609,2609],\\\"disallowed\\\"],[[2610,2610],\\\"valid\\\"],[[2611,2611],\\\"mapped\\\",[2610,2620]],[[2612,2612],\\\"disallowed\\\"],[[2613,2613],\\\"valid\\\"],[[2614,2614],\\\"mapped\\\",[2616,2620]],[[2615,2615],\\\"disallowed\\\"],[[2616,2617],\\\"valid\\\"],[[2618,2619],\\\"disallowed\\\"],[[2620,2620],\\\"valid\\\"],[[2621,2621],\\\"disallowed\\\"],[[2622,2626],\\\"valid\\\"],[[2627,2630],\\\"disallowed\\\"],[[2631,2632],\\\"valid\\\"],[[2633,2634],\\\"disallowed\\\"],[[2635,2637],\\\"valid\\\"],[[2638,2640],\\\"disallowed\\\"],[[2641,2641],\\\"valid\\\"],[[2642,2648],\\\"disallowed\\\"],[[2649,2649],\\\"mapped\\\",[2582,2620]],[[2650,2650],\\\"mapped\\\",[2583,2620]],[[2651,2651],\\\"mapped\\\",[2588,2620]],[[2652,2652],\\\"valid\\\"],[[2653,2653],\\\"disallowed\\\"],[[2654,2654],\\\"mapped\\\",[2603,2620]],[[2655,2661],\\\"disallowed\\\"],[[2662,2676],\\\"valid\\\"],[[2677,2677],\\\"valid\\\"],[[2678,2688],\\\"disallowed\\\"],[[2689,2691],\\\"valid\\\"],[[2692,2692],\\\"disallowed\\\"],[[2693,2699],\\\"valid\\\"],[[2700,2700],\\\"valid\\\"],[[2701,2701],\\\"valid\\\"],[[2702,2702],\\\"disallowed\\\"],[[2703,2705],\\\"valid\\\"],[[2706,2706],\\\"disallowed\\\"],[[2707,2728],\\\"valid\\\"],[[2729,2729],\\\"disallowed\\\"],[[2730,2736],\\\"valid\\\"],[[2737,2737],\\\"disallowed\\\"],[[2738,2739],\\\"valid\\\"],[[2740,2740],\\\"disallowed\\\"],[[2741,2745],\\\"valid\\\"],[[2746,2747],\\\"disallowed\\\"],[[2748,2757],\\\"valid\\\"],[[2758,2758],\\\"disallowed\\\"],[[2759,2761],\\\"valid\\\"],[[2762,2762],\\\"disallowed\\\"],[[2763,2765],\\\"valid\\\"],[[2766,2767],\\\"disallowed\\\"],[[2768,2768],\\\"valid\\\"],[[2769,2783],\\\"disallowed\\\"],[[2784,2784],\\\"valid\\\"],[[2785,2787],\\\"valid\\\"],[[2788,2789],\\\"disallowed\\\"],[[2790,2799],\\\"valid\\\"],[[2800,2800],\\\"valid\\\",[],\\\"NV8\\\"],[[2801,2801],\\\"valid\\\",[],\\\"NV8\\\"],[[2802,2808],\\\"disallowed\\\"],[[2809,2809],\\\"valid\\\"],[[2810,2816],\\\"disallowed\\\"],[[2817,2819],\\\"valid\\\"],[[2820,2820],\\\"disallowed\\\"],[[2821,2828],\\\"valid\\\"],[[2829,2830],\\\"disallowed\\\"],[[2831,2832],\\\"valid\\\"],[[2833,2834],\\\"disallowed\\\"],[[2835,2856],\\\"valid\\\"],[[2857,2857],\\\"disallowed\\\"],[[2858,2864],\\\"valid\\\"],[[2865,2865],\\\"disallowed\\\"],[[2866,2867],\\\"valid\\\"],[[2868,2868],\\\"disallowed\\\"],[[2869,2869],\\\"valid\\\"],[[2870,2873],\\\"valid\\\"],[[2874,2875],\\\"disallowed\\\"],[[2876,2883],\\\"valid\\\"],[[2884,2884],\\\"valid\\\"],[[2885,2886],\\\"disallowed\\\"],[[2887,2888],\\\"valid\\\"],[[2889,2890],\\\"disallowed\\\"],[[2891,2893],\\\"valid\\\"],[[2894,2901],\\\"disallowed\\\"],[[2902,2903],\\\"valid\\\"],[[2904,2907],\\\"disallowed\\\"],[[2908,2908],\\\"mapped\\\",[2849,2876]],[[2909,2909],\\\"mapped\\\",[2850,2876]],[[2910,2910],\\\"disallowed\\\"],[[2911,2913],\\\"valid\\\"],[[2914,2915],\\\"valid\\\"],[[2916,2917],\\\"disallowed\\\"],[[2918,2927],\\\"valid\\\"],[[2928,2928],\\\"valid\\\",[],\\\"NV8\\\"],[[2929,2929],\\\"valid\\\"],[[2930,2935],\\\"valid\\\",[],\\\"NV8\\\"],[[2936,2945],\\\"disallowed\\\"],[[2946,2947],\\\"valid\\\"],[[2948,2948],\\\"disallowed\\\"],[[2949,2954],\\\"valid\\\"],[[2955,2957],\\\"disallowed\\\"],[[2958,2960],\\\"valid\\\"],[[2961,2961],\\\"disallowed\\\"],[[2962,2965],\\\"valid\\\"],[[2966,2968],\\\"disallowed\\\"],[[2969,2970],\\\"valid\\\"],[[2971,2971],\\\"disallowed\\\"],[[2972,2972],\\\"valid\\\"],[[2973,2973],\\\"disallowed\\\"],[[2974,2975],\\\"valid\\\"],[[2976,2978],\\\"disallowed\\\"],[[2979,2980],\\\"valid\\\"],[[2981,2983],\\\"disallowed\\\"],[[2984,2986],\\\"valid\\\"],[[2987,2989],\\\"disallowed\\\"],[[2990,2997],\\\"valid\\\"],[[2998,2998],\\\"valid\\\"],[[2999,3001],\\\"valid\\\"],[[3002,3005],\\\"disallowed\\\"],[[3006,3010],\\\"valid\\\"],[[3011,3013],\\\"disallowed\\\"],[[3014,3016],\\\"valid\\\"],[[3017,3017],\\\"disallowed\\\"],[[3018,3021],\\\"valid\\\"],[[3022,3023],\\\"disallowed\\\"],[[3024,3024],\\\"valid\\\"],[[3025,3030],\\\"disallowed\\\"],[[3031,3031],\\\"valid\\\"],[[3032,3045],\\\"disallowed\\\"],[[3046,3046],\\\"valid\\\"],[[3047,3055],\\\"valid\\\"],[[3056,3058],\\\"valid\\\",[],\\\"NV8\\\"],[[3059,3066],\\\"valid\\\",[],\\\"NV8\\\"],[[3067,3071],\\\"disallowed\\\"],[[3072,3072],\\\"valid\\\"],[[3073,3075],\\\"valid\\\"],[[3076,3076],\\\"disallowed\\\"],[[3077,3084],\\\"valid\\\"],[[3085,3085],\\\"disallowed\\\"],[[3086,3088],\\\"valid\\\"],[[3089,3089],\\\"disallowed\\\"],[[3090,3112],\\\"valid\\\"],[[3113,3113],\\\"disallowed\\\"],[[3114,3123],\\\"valid\\\"],[[3124,3124],\\\"valid\\\"],[[3125,3129],\\\"valid\\\"],[[3130,3132],\\\"disallowed\\\"],[[3133,3133],\\\"valid\\\"],[[3134,3140],\\\"valid\\\"],[[3141,3141],\\\"disallowed\\\"],[[3142,3144],\\\"valid\\\"],[[3145,3145],\\\"disallowed\\\"],[[3146,3149],\\\"valid\\\"],[[3150,3156],\\\"disallowed\\\"],[[3157,3158],\\\"valid\\\"],[[3159,3159],\\\"disallowed\\\"],[[3160,3161],\\\"valid\\\"],[[3162,3162],\\\"valid\\\"],[[3163,3167],\\\"disallowed\\\"],[[3168,3169],\\\"valid\\\"],[[3170,3171],\\\"valid\\\"],[[3172,3173],\\\"disallowed\\\"],[[3174,3183],\\\"valid\\\"],[[3184,3191],\\\"disallowed\\\"],[[3192,3199],\\\"valid\\\",[],\\\"NV8\\\"],[[3200,3200],\\\"disallowed\\\"],[[3201,3201],\\\"valid\\\"],[[3202,3203],\\\"valid\\\"],[[3204,3204],\\\"disallowed\\\"],[[3205,3212],\\\"valid\\\"],[[3213,3213],\\\"disallowed\\\"],[[3214,3216],\\\"valid\\\"],[[3217,3217],\\\"disallowed\\\"],[[3218,3240],\\\"valid\\\"],[[3241,3241],\\\"disallowed\\\"],[[3242,3251],\\\"valid\\\"],[[3252,3252],\\\"disallowed\\\"],[[3253,3257],\\\"valid\\\"],[[3258,3259],\\\"disallowed\\\"],[[3260,3261],\\\"valid\\\"],[[3262,3268],\\\"valid\\\"],[[3269,3269],\\\"disallowed\\\"],[[3270,3272],\\\"valid\\\"],[[3273,3273],\\\"disallowed\\\"],[[3274,3277],\\\"valid\\\"],[[3278,3284],\\\"disallowed\\\"],[[3285,3286],\\\"valid\\\"],[[3287,3293],\\\"disallowed\\\"],[[3294,3294],\\\"valid\\\"],[[3295,3295],\\\"disallowed\\\"],[[3296,3297],\\\"valid\\\"],[[3298,3299],\\\"valid\\\"],[[3300,3301],\\\"disallowed\\\"],[[3302,3311],\\\"valid\\\"],[[3312,3312],\\\"disallowed\\\"],[[3313,3314],\\\"valid\\\"],[[3315,3328],\\\"disallowed\\\"],[[3329,3329],\\\"valid\\\"],[[3330,3331],\\\"valid\\\"],[[3332,3332],\\\"disallowed\\\"],[[3333,3340],\\\"valid\\\"],[[3341,3341],\\\"disallowed\\\"],[[3342,3344],\\\"valid\\\"],[[3345,3345],\\\"disallowed\\\"],[[3346,3368],\\\"valid\\\"],[[3369,3369],\\\"valid\\\"],[[3370,3385],\\\"valid\\\"],[[3386,3386],\\\"valid\\\"],[[3387,3388],\\\"disallowed\\\"],[[3389,3389],\\\"valid\\\"],[[3390,3395],\\\"valid\\\"],[[3396,3396],\\\"valid\\\"],[[3397,3397],\\\"disallowed\\\"],[[3398,3400],\\\"valid\\\"],[[3401,3401],\\\"disallowed\\\"],[[3402,3405],\\\"valid\\\"],[[3406,3406],\\\"valid\\\"],[[3407,3414],\\\"disallowed\\\"],[[3415,3415],\\\"valid\\\"],[[3416,3422],\\\"disallowed\\\"],[[3423,3423],\\\"valid\\\"],[[3424,3425],\\\"valid\\\"],[[3426,3427],\\\"valid\\\"],[[3428,3429],\\\"disallowed\\\"],[[3430,3439],\\\"valid\\\"],[[3440,3445],\\\"valid\\\",[],\\\"NV8\\\"],[[3446,3448],\\\"disallowed\\\"],[[3449,3449],\\\"valid\\\",[],\\\"NV8\\\"],[[3450,3455],\\\"valid\\\"],[[3456,3457],\\\"disallowed\\\"],[[3458,3459],\\\"valid\\\"],[[3460,3460],\\\"disallowed\\\"],[[3461,3478],\\\"valid\\\"],[[3479,3481],\\\"disallowed\\\"],[[3482,3505],\\\"valid\\\"],[[3506,3506],\\\"disallowed\\\"],[[3507,3515],\\\"valid\\\"],[[3516,3516],\\\"disallowed\\\"],[[3517,3517],\\\"valid\\\"],[[3518,3519],\\\"disallowed\\\"],[[3520,3526],\\\"valid\\\"],[[3527,3529],\\\"disallowed\\\"],[[3530,3530],\\\"valid\\\"],[[3531,3534],\\\"disallowed\\\"],[[3535,3540],\\\"valid\\\"],[[3541,3541],\\\"disallowed\\\"],[[3542,3542],\\\"valid\\\"],[[3543,3543],\\\"disallowed\\\"],[[3544,3551],\\\"valid\\\"],[[3552,3557],\\\"disallowed\\\"],[[3558,3567],\\\"valid\\\"],[[3568,3569],\\\"disallowed\\\"],[[3570,3571],\\\"valid\\\"],[[3572,3572],\\\"valid\\\",[],\\\"NV8\\\"],[[3573,3584],\\\"disallowed\\\"],[[3585,3634],\\\"valid\\\"],[[3635,3635],\\\"mapped\\\",[3661,3634]],[[3636,3642],\\\"valid\\\"],[[3643,3646],\\\"disallowed\\\"],[[3647,3647],\\\"valid\\\",[],\\\"NV8\\\"],[[3648,3662],\\\"valid\\\"],[[3663,3663],\\\"valid\\\",[],\\\"NV8\\\"],[[3664,3673],\\\"valid\\\"],[[3674,3675],\\\"valid\\\",[],\\\"NV8\\\"],[[3676,3712],\\\"disallowed\\\"],[[3713,3714],\\\"valid\\\"],[[3715,3715],\\\"disallowed\\\"],[[3716,3716],\\\"valid\\\"],[[3717,3718],\\\"disallowed\\\"],[[3719,3720],\\\"valid\\\"],[[3721,3721],\\\"disallowed\\\"],[[3722,3722],\\\"valid\\\"],[[3723,3724],\\\"disallowed\\\"],[[3725,3725],\\\"valid\\\"],[[3726,3731],\\\"disallowed\\\"],[[3732,3735],\\\"valid\\\"],[[3736,3736],\\\"disallowed\\\"],[[3737,3743],\\\"valid\\\"],[[3744,3744],\\\"disallowed\\\"],[[3745,3747],\\\"valid\\\"],[[3748,3748],\\\"disallowed\\\"],[[3749,3749],\\\"valid\\\"],[[3750,3750],\\\"disallowed\\\"],[[3751,3751],\\\"valid\\\"],[[3752,3753],\\\"disallowed\\\"],[[3754,3755],\\\"valid\\\"],[[3756,3756],\\\"disallowed\\\"],[[3757,3762],\\\"valid\\\"],[[3763,3763],\\\"mapped\\\",[3789,3762]],[[3764,3769],\\\"valid\\\"],[[3770,3770],\\\"disallowed\\\"],[[3771,3773],\\\"valid\\\"],[[3774,3775],\\\"disallowed\\\"],[[3776,3780],\\\"valid\\\"],[[3781,3781],\\\"disallowed\\\"],[[3782,3782],\\\"valid\\\"],[[3783,3783],\\\"disallowed\\\"],[[3784,3789],\\\"valid\\\"],[[3790,3791],\\\"disallowed\\\"],[[3792,3801],\\\"valid\\\"],[[3802,3803],\\\"disallowed\\\"],[[3804,3804],\\\"mapped\\\",[3755,3737]],[[3805,3805],\\\"mapped\\\",[3755,3745]],[[3806,3807],\\\"valid\\\"],[[3808,3839],\\\"disallowed\\\"],[[3840,3840],\\\"valid\\\"],[[3841,3850],\\\"valid\\\",[],\\\"NV8\\\"],[[3851,3851],\\\"valid\\\"],[[3852,3852],\\\"mapped\\\",[3851]],[[3853,3863],\\\"valid\\\",[],\\\"NV8\\\"],[[3864,3865],\\\"valid\\\"],[[3866,3871],\\\"valid\\\",[],\\\"NV8\\\"],[[3872,3881],\\\"valid\\\"],[[3882,3892],\\\"valid\\\",[],\\\"NV8\\\"],[[3893,3893],\\\"valid\\\"],[[3894,3894],\\\"valid\\\",[],\\\"NV8\\\"],[[3895,3895],\\\"valid\\\"],[[3896,3896],\\\"valid\\\",[],\\\"NV8\\\"],[[3897,3897],\\\"valid\\\"],[[3898,3901],\\\"valid\\\",[],\\\"NV8\\\"],[[3902,3906],\\\"valid\\\"],[[3907,3907],\\\"mapped\\\",[3906,4023]],[[3908,3911],\\\"valid\\\"],[[3912,3912],\\\"disallowed\\\"],[[3913,3916],\\\"valid\\\"],[[3917,3917],\\\"mapped\\\",[3916,4023]],[[3918,3921],\\\"valid\\\"],[[3922,3922],\\\"mapped\\\",[3921,4023]],[[3923,3926],\\\"valid\\\"],[[3927,3927],\\\"mapped\\\",[3926,4023]],[[3928,3931],\\\"valid\\\"],[[3932,3932],\\\"mapped\\\",[3931,4023]],[[3933,3944],\\\"valid\\\"],[[3945,3945],\\\"mapped\\\",[3904,4021]],[[3946,3946],\\\"valid\\\"],[[3947,3948],\\\"valid\\\"],[[3949,3952],\\\"disallowed\\\"],[[3953,3954],\\\"valid\\\"],[[3955,3955],\\\"mapped\\\",[3953,3954]],[[3956,3956],\\\"valid\\\"],[[3957,3957],\\\"mapped\\\",[3953,3956]],[[3958,3958],\\\"mapped\\\",[4018,3968]],[[3959,3959],\\\"mapped\\\",[4018,3953,3968]],[[3960,3960],\\\"mapped\\\",[4019,3968]],[[3961,3961],\\\"mapped\\\",[4019,3953,3968]],[[3962,3968],\\\"valid\\\"],[[3969,3969],\\\"mapped\\\",[3953,3968]],[[3970,3972],\\\"valid\\\"],[[3973,3973],\\\"valid\\\",[],\\\"NV8\\\"],[[3974,3979],\\\"valid\\\"],[[3980,3983],\\\"valid\\\"],[[3984,3986],\\\"valid\\\"],[[3987,3987],\\\"mapped\\\",[3986,4023]],[[3988,3989],\\\"valid\\\"],[[3990,3990],\\\"valid\\\"],[[3991,3991],\\\"valid\\\"],[[3992,3992],\\\"disallowed\\\"],[[3993,3996],\\\"valid\\\"],[[3997,3997],\\\"mapped\\\",[3996,4023]],[[3998,4001],\\\"valid\\\"],[[4002,4002],\\\"mapped\\\",[4001,4023]],[[4003,4006],\\\"valid\\\"],[[4007,4007],\\\"mapped\\\",[4006,4023]],[[4008,4011],\\\"valid\\\"],[[4012,4012],\\\"mapped\\\",[4011,4023]],[[4013,4013],\\\"valid\\\"],[[4014,4016],\\\"valid\\\"],[[4017,4023],\\\"valid\\\"],[[4024,4024],\\\"valid\\\"],[[4025,4025],\\\"mapped\\\",[3984,4021]],[[4026,4028],\\\"valid\\\"],[[4029,4029],\\\"disallowed\\\"],[[4030,4037],\\\"valid\\\",[],\\\"NV8\\\"],[[4038,4038],\\\"valid\\\"],[[4039,4044],\\\"valid\\\",[],\\\"NV8\\\"],[[4045,4045],\\\"disallowed\\\"],[[4046,4046],\\\"valid\\\",[],\\\"NV8\\\"],[[4047,4047],\\\"valid\\\",[],\\\"NV8\\\"],[[4048,4049],\\\"valid\\\",[],\\\"NV8\\\"],[[4050,4052],\\\"valid\\\",[],\\\"NV8\\\"],[[4053,4056],\\\"valid\\\",[],\\\"NV8\\\"],[[4057,4058],\\\"valid\\\",[],\\\"NV8\\\"],[[4059,4095],\\\"disallowed\\\"],[[4096,4129],\\\"valid\\\"],[[4130,4130],\\\"valid\\\"],[[4131,4135],\\\"valid\\\"],[[4136,4136],\\\"valid\\\"],[[4137,4138],\\\"valid\\\"],[[4139,4139],\\\"valid\\\"],[[4140,4146],\\\"valid\\\"],[[4147,4149],\\\"valid\\\"],[[4150,4153],\\\"valid\\\"],[[4154,4159],\\\"valid\\\"],[[4160,4169],\\\"valid\\\"],[[4170,4175],\\\"valid\\\",[],\\\"NV8\\\"],[[4176,4185],\\\"valid\\\"],[[4186,4249],\\\"valid\\\"],[[4250,4253],\\\"valid\\\"],[[4254,4255],\\\"valid\\\",[],\\\"NV8\\\"],[[4256,4293],\\\"disallowed\\\"],[[4294,4294],\\\"disallowed\\\"],[[4295,4295],\\\"mapped\\\",[11559]],[[4296,4300],\\\"disallowed\\\"],[[4301,4301],\\\"mapped\\\",[11565]],[[4302,4303],\\\"disallowed\\\"],[[4304,4342],\\\"valid\\\"],[[4343,4344],\\\"valid\\\"],[[4345,4346],\\\"valid\\\"],[[4347,4347],\\\"valid\\\",[],\\\"NV8\\\"],[[4348,4348],\\\"mapped\\\",[4316]],[[4349,4351],\\\"valid\\\"],[[4352,4441],\\\"valid\\\",[],\\\"NV8\\\"],[[4442,4446],\\\"valid\\\",[],\\\"NV8\\\"],[[4447,4448],\\\"disallowed\\\"],[[4449,4514],\\\"valid\\\",[],\\\"NV8\\\"],[[4515,4519],\\\"valid\\\",[],\\\"NV8\\\"],[[4520,4601],\\\"valid\\\",[],\\\"NV8\\\"],[[4602,4607],\\\"valid\\\",[],\\\"NV8\\\"],[[4608,4614],\\\"valid\\\"],[[4615,4615],\\\"valid\\\"],[[4616,4678],\\\"valid\\\"],[[4679,4679],\\\"valid\\\"],[[4680,4680],\\\"valid\\\"],[[4681,4681],\\\"disallowed\\\"],[[4682,4685],\\\"valid\\\"],[[4686,4687],\\\"disallowed\\\"],[[4688,4694],\\\"valid\\\"],[[4695,4695],\\\"disallowed\\\"],[[4696,4696],\\\"valid\\\"],[[4697,4697],\\\"disallowed\\\"],[[4698,4701],\\\"valid\\\"],[[4702,4703],\\\"disallowed\\\"],[[4704,4742],\\\"valid\\\"],[[4743,4743],\\\"valid\\\"],[[4744,4744],\\\"valid\\\"],[[4745,4745],\\\"disallowed\\\"],[[4746,4749],\\\"valid\\\"],[[4750,4751],\\\"disallowed\\\"],[[4752,4782],\\\"valid\\\"],[[4783,4783],\\\"valid\\\"],[[4784,4784],\\\"valid\\\"],[[4785,4785],\\\"disallowed\\\"],[[4786,4789],\\\"valid\\\"],[[4790,4791],\\\"disallowed\\\"],[[4792,4798],\\\"valid\\\"],[[4799,4799],\\\"disallowed\\\"],[[4800,4800],\\\"valid\\\"],[[4801,4801],\\\"disallowed\\\"],[[4802,4805],\\\"valid\\\"],[[4806,4807],\\\"disallowed\\\"],[[4808,4814],\\\"valid\\\"],[[4815,4815],\\\"valid\\\"],[[4816,4822],\\\"valid\\\"],[[4823,4823],\\\"disallowed\\\"],[[4824,4846],\\\"valid\\\"],[[4847,4847],\\\"valid\\\"],[[4848,4878],\\\"valid\\\"],[[4879,4879],\\\"valid\\\"],[[4880,4880],\\\"valid\\\"],[[4881,4881],\\\"disallowed\\\"],[[4882,4885],\\\"valid\\\"],[[4886,4887],\\\"disallowed\\\"],[[4888,4894],\\\"valid\\\"],[[4895,4895],\\\"valid\\\"],[[4896,4934],\\\"valid\\\"],[[4935,4935],\\\"valid\\\"],[[4936,4954],\\\"valid\\\"],[[4955,4956],\\\"disallowed\\\"],[[4957,4958],\\\"valid\\\"],[[4959,4959],\\\"valid\\\"],[[4960,4960],\\\"valid\\\",[],\\\"NV8\\\"],[[4961,4988],\\\"valid\\\",[],\\\"NV8\\\"],[[4989,4991],\\\"disallowed\\\"],[[4992,5007],\\\"valid\\\"],[[5008,5017],\\\"valid\\\",[],\\\"NV8\\\"],[[5018,5023],\\\"disallowed\\\"],[[5024,5108],\\\"valid\\\"],[[5109,5109],\\\"valid\\\"],[[5110,5111],\\\"disallowed\\\"],[[5112,5112],\\\"mapped\\\",[5104]],[[5113,5113],\\\"mapped\\\",[5105]],[[5114,5114],\\\"mapped\\\",[5106]],[[5115,5115],\\\"mapped\\\",[5107]],[[5116,5116],\\\"mapped\\\",[5108]],[[5117,5117],\\\"mapped\\\",[5109]],[[5118,5119],\\\"disallowed\\\"],[[5120,5120],\\\"valid\\\",[],\\\"NV8\\\"],[[5121,5740],\\\"valid\\\"],[[5741,5742],\\\"valid\\\",[],\\\"NV8\\\"],[[5743,5750],\\\"valid\\\"],[[5751,5759],\\\"valid\\\"],[[5760,5760],\\\"disallowed\\\"],[[5761,5786],\\\"valid\\\"],[[5787,5788],\\\"valid\\\",[],\\\"NV8\\\"],[[5789,5791],\\\"disallowed\\\"],[[5792,5866],\\\"valid\\\"],[[5867,5872],\\\"valid\\\",[],\\\"NV8\\\"],[[5873,5880],\\\"valid\\\"],[[5881,5887],\\\"disallowed\\\"],[[5888,5900],\\\"valid\\\"],[[5901,5901],\\\"disallowed\\\"],[[5902,5908],\\\"valid\\\"],[[5909,5919],\\\"disallowed\\\"],[[5920,5940],\\\"valid\\\"],[[5941,5942],\\\"valid\\\",[],\\\"NV8\\\"],[[5943,5951],\\\"disallowed\\\"],[[5952,5971],\\\"valid\\\"],[[5972,5983],\\\"disallowed\\\"],[[5984,5996],\\\"valid\\\"],[[5997,5997],\\\"disallowed\\\"],[[5998,6000],\\\"valid\\\"],[[6001,6001],\\\"disallowed\\\"],[[6002,6003],\\\"valid\\\"],[[6004,6015],\\\"disallowed\\\"],[[6016,6067],\\\"valid\\\"],[[6068,6069],\\\"disallowed\\\"],[[6070,6099],\\\"valid\\\"],[[6100,6102],\\\"valid\\\",[],\\\"NV8\\\"],[[6103,6103],\\\"valid\\\"],[[6104,6107],\\\"valid\\\",[],\\\"NV8\\\"],[[6108,6108],\\\"valid\\\"],[[6109,6109],\\\"valid\\\"],[[6110,6111],\\\"disallowed\\\"],[[6112,6121],\\\"valid\\\"],[[6122,6127],\\\"disallowed\\\"],[[6128,6137],\\\"valid\\\",[],\\\"NV8\\\"],[[6138,6143],\\\"disallowed\\\"],[[6144,6149],\\\"valid\\\",[],\\\"NV8\\\"],[[6150,6150],\\\"disallowed\\\"],[[6151,6154],\\\"valid\\\",[],\\\"NV8\\\"],[[6155,6157],\\\"ignored\\\"],[[6158,6158],\\\"disallowed\\\"],[[6159,6159],\\\"disallowed\\\"],[[6160,6169],\\\"valid\\\"],[[6170,6175],\\\"disallowed\\\"],[[6176,6263],\\\"valid\\\"],[[6264,6271],\\\"disallowed\\\"],[[6272,6313],\\\"valid\\\"],[[6314,6314],\\\"valid\\\"],[[6315,6319],\\\"disallowed\\\"],[[6320,6389],\\\"valid\\\"],[[6390,6399],\\\"disallowed\\\"],[[6400,6428],\\\"valid\\\"],[[6429,6430],\\\"valid\\\"],[[6431,6431],\\\"disallowed\\\"],[[6432,6443],\\\"valid\\\"],[[6444,6447],\\\"disallowed\\\"],[[6448,6459],\\\"valid\\\"],[[6460,6463],\\\"disallowed\\\"],[[6464,6464],\\\"valid\\\",[],\\\"NV8\\\"],[[6465,6467],\\\"disallowed\\\"],[[6468,6469],\\\"valid\\\",[],\\\"NV8\\\"],[[6470,6509],\\\"valid\\\"],[[6510,6511],\\\"disallowed\\\"],[[6512,6516],\\\"valid\\\"],[[6517,6527],\\\"disallowed\\\"],[[6528,6569],\\\"valid\\\"],[[6570,6571],\\\"valid\\\"],[[6572,6575],\\\"disallowed\\\"],[[6576,6601],\\\"valid\\\"],[[6602,6607],\\\"disallowed\\\"],[[6608,6617],\\\"valid\\\"],[[6618,6618],\\\"valid\\\",[],\\\"XV8\\\"],[[6619,6621],\\\"disallowed\\\"],[[6622,6623],\\\"valid\\\",[],\\\"NV8\\\"],[[6624,6655],\\\"valid\\\",[],\\\"NV8\\\"],[[6656,6683],\\\"valid\\\"],[[6684,6685],\\\"disallowed\\\"],[[6686,6687],\\\"valid\\\",[],\\\"NV8\\\"],[[6688,6750],\\\"valid\\\"],[[6751,6751],\\\"disallowed\\\"],[[6752,6780],\\\"valid\\\"],[[6781,6782],\\\"disallowed\\\"],[[6783,6793],\\\"valid\\\"],[[6794,6799],\\\"disallowed\\\"],[[6800,6809],\\\"valid\\\"],[[6810,6815],\\\"disallowed\\\"],[[6816,6822],\\\"valid\\\",[],\\\"NV8\\\"],[[6823,6823],\\\"valid\\\"],[[6824,6829],\\\"valid\\\",[],\\\"NV8\\\"],[[6830,6831],\\\"disallowed\\\"],[[6832,6845],\\\"valid\\\"],[[6846,6846],\\\"valid\\\",[],\\\"NV8\\\"],[[6847,6911],\\\"disallowed\\\"],[[6912,6987],\\\"valid\\\"],[[6988,6991],\\\"disallowed\\\"],[[6992,7001],\\\"valid\\\"],[[7002,7018],\\\"valid\\\",[],\\\"NV8\\\"],[[7019,7027],\\\"valid\\\"],[[7028,7036],\\\"valid\\\",[],\\\"NV8\\\"],[[7037,7039],\\\"disallowed\\\"],[[7040,7082],\\\"valid\\\"],[[7083,7085],\\\"valid\\\"],[[7086,7097],\\\"valid\\\"],[[7098,7103],\\\"valid\\\"],[[7104,7155],\\\"valid\\\"],[[7156,7163],\\\"disallowed\\\"],[[7164,7167],\\\"valid\\\",[],\\\"NV8\\\"],[[7168,7223],\\\"valid\\\"],[[7224,7226],\\\"disallowed\\\"],[[7227,7231],\\\"valid\\\",[],\\\"NV8\\\"],[[7232,7241],\\\"valid\\\"],[[7242,7244],\\\"disallowed\\\"],[[7245,7293],\\\"valid\\\"],[[7294,7295],\\\"valid\\\",[],\\\"NV8\\\"],[[7296,7359],\\\"disallowed\\\"],[[7360,7367],\\\"valid\\\",[],\\\"NV8\\\"],[[7368,7375],\\\"disallowed\\\"],[[7376,7378],\\\"valid\\\"],[[7379,7379],\\\"valid\\\",[],\\\"NV8\\\"],[[7380,7410],\\\"valid\\\"],[[7411,7414],\\\"valid\\\"],[[7415,7415],\\\"disallowed\\\"],[[7416,7417],\\\"valid\\\"],[[7418,7423],\\\"disallowed\\\"],[[7424,7467],\\\"valid\\\"],[[7468,7468],\\\"mapped\\\",[97]],[[7469,7469],\\\"mapped\\\",[230]],[[7470,7470],\\\"mapped\\\",[98]],[[7471,7471],\\\"valid\\\"],[[7472,7472],\\\"mapped\\\",[100]],[[7473,7473],\\\"mapped\\\",[101]],[[7474,7474],\\\"mapped\\\",[477]],[[7475,7475],\\\"mapped\\\",[103]],[[7476,7476],\\\"mapped\\\",[104]],[[7477,7477],\\\"mapped\\\",[105]],[[7478,7478],\\\"mapped\\\",[106]],[[7479,7479],\\\"mapped\\\",[107]],[[7480,7480],\\\"mapped\\\",[108]],[[7481,7481],\\\"mapped\\\",[109]],[[7482,7482],\\\"mapped\\\",[110]],[[7483,7483],\\\"valid\\\"],[[7484,7484],\\\"mapped\\\",[111]],[[7485,7485],\\\"mapped\\\",[547]],[[7486,7486],\\\"mapped\\\",[112]],[[7487,7487],\\\"mapped\\\",[114]],[[7488,7488],\\\"mapped\\\",[116]],[[7489,7489],\\\"mapped\\\",[117]],[[7490,7490],\\\"mapped\\\",[119]],[[7491,7491],\\\"mapped\\\",[97]],[[7492,7492],\\\"mapped\\\",[592]],[[7493,7493],\\\"mapped\\\",[593]],[[7494,7494],\\\"mapped\\\",[7426]],[[7495,7495],\\\"mapped\\\",[98]],[[7496,7496],\\\"mapped\\\",[100]],[[7497,7497],\\\"mapped\\\",[101]],[[7498,7498],\\\"mapped\\\",[601]],[[7499,7499],\\\"mapped\\\",[603]],[[7500,7500],\\\"mapped\\\",[604]],[[7501,7501],\\\"mapped\\\",[103]],[[7502,7502],\\\"valid\\\"],[[7503,7503],\\\"mapped\\\",[107]],[[7504,7504],\\\"mapped\\\",[109]],[[7505,7505],\\\"mapped\\\",[331]],[[7506,7506],\\\"mapped\\\",[111]],[[7507,7507],\\\"mapped\\\",[596]],[[7508,7508],\\\"mapped\\\",[7446]],[[7509,7509],\\\"mapped\\\",[7447]],[[7510,7510],\\\"mapped\\\",[112]],[[7511,7511],\\\"mapped\\\",[116]],[[7512,7512],\\\"mapped\\\",[117]],[[7513,7513],\\\"mapped\\\",[7453]],[[7514,7514],\\\"mapped\\\",[623]],[[7515,7515],\\\"mapped\\\",[118]],[[7516,7516],\\\"mapped\\\",[7461]],[[7517,7517],\\\"mapped\\\",[946]],[[7518,7518],\\\"mapped\\\",[947]],[[7519,7519],\\\"mapped\\\",[948]],[[7520,7520],\\\"mapped\\\",[966]],[[7521,7521],\\\"mapped\\\",[967]],[[7522,7522],\\\"mapped\\\",[105]],[[7523,7523],\\\"mapped\\\",[114]],[[7524,7524],\\\"mapped\\\",[117]],[[7525,7525],\\\"mapped\\\",[118]],[[7526,7526],\\\"mapped\\\",[946]],[[7527,7527],\\\"mapped\\\",[947]],[[7528,7528],\\\"mapped\\\",[961]],[[7529,7529],\\\"mapped\\\",[966]],[[7530,7530],\\\"mapped\\\",[967]],[[7531,7531],\\\"valid\\\"],[[7532,7543],\\\"valid\\\"],[[7544,7544],\\\"mapped\\\",[1085]],[[7545,7578],\\\"valid\\\"],[[7579,7579],\\\"mapped\\\",[594]],[[7580,7580],\\\"mapped\\\",[99]],[[7581,7581],\\\"mapped\\\",[597]],[[7582,7582],\\\"mapped\\\",[240]],[[7583,7583],\\\"mapped\\\",[604]],[[7584,7584],\\\"mapped\\\",[102]],[[7585,7585],\\\"mapped\\\",[607]],[[7586,7586],\\\"mapped\\\",[609]],[[7587,7587],\\\"mapped\\\",[613]],[[7588,7588],\\\"mapped\\\",[616]],[[7589,7589],\\\"mapped\\\",[617]],[[7590,7590],\\\"mapped\\\",[618]],[[7591,7591],\\\"mapped\\\",[7547]],[[7592,7592],\\\"mapped\\\",[669]],[[7593,7593],\\\"mapped\\\",[621]],[[7594,7594],\\\"mapped\\\",[7557]],[[7595,7595],\\\"mapped\\\",[671]],[[7596,7596],\\\"mapped\\\",[625]],[[7597,7597],\\\"mapped\\\",[624]],[[7598,7598],\\\"mapped\\\",[626]],[[7599,7599],\\\"mapped\\\",[627]],[[7600,7600],\\\"mapped\\\",[628]],[[7601,7601],\\\"mapped\\\",[629]],[[7602,7602],\\\"mapped\\\",[632]],[[7603,7603],\\\"mapped\\\",[642]],[[7604,7604],\\\"mapped\\\",[643]],[[7605,7605],\\\"mapped\\\",[427]],[[7606,7606],\\\"mapped\\\",[649]],[[7607,7607],\\\"mapped\\\",[650]],[[7608,7608],\\\"mapped\\\",[7452]],[[7609,7609],\\\"mapped\\\",[651]],[[7610,7610],\\\"mapped\\\",[652]],[[7611,7611],\\\"mapped\\\",[122]],[[7612,7612],\\\"mapped\\\",[656]],[[7613,7613],\\\"mapped\\\",[657]],[[7614,7614],\\\"mapped\\\",[658]],[[7615,7615],\\\"mapped\\\",[952]],[[7616,7619],\\\"valid\\\"],[[7620,7626],\\\"valid\\\"],[[7627,7654],\\\"valid\\\"],[[7655,7669],\\\"valid\\\"],[[7670,7675],\\\"disallowed\\\"],[[7676,7676],\\\"valid\\\"],[[7677,7677],\\\"valid\\\"],[[7678,7679],\\\"valid\\\"],[[7680,7680],\\\"mapped\\\",[7681]],[[7681,7681],\\\"valid\\\"],[[7682,7682],\\\"mapped\\\",[7683]],[[7683,7683],\\\"valid\\\"],[[7684,7684],\\\"mapped\\\",[7685]],[[7685,7685],\\\"valid\\\"],[[7686,7686],\\\"mapped\\\",[7687]],[[7687,7687],\\\"valid\\\"],[[7688,7688],\\\"mapped\\\",[7689]],[[7689,7689],\\\"valid\\\"],[[7690,7690],\\\"mapped\\\",[7691]],[[7691,7691],\\\"valid\\\"],[[7692,7692],\\\"mapped\\\",[7693]],[[7693,7693],\\\"valid\\\"],[[7694,7694],\\\"mapped\\\",[7695]],[[7695,7695],\\\"valid\\\"],[[7696,7696],\\\"mapped\\\",[7697]],[[7697,7697],\\\"valid\\\"],[[7698,7698],\\\"mapped\\\",[7699]],[[7699,7699],\\\"valid\\\"],[[7700,7700],\\\"mapped\\\",[7701]],[[7701,7701],\\\"valid\\\"],[[7702,7702],\\\"mapped\\\",[7703]],[[7703,7703],\\\"valid\\\"],[[7704,7704],\\\"mapped\\\",[7705]],[[7705,7705],\\\"valid\\\"],[[7706,7706],\\\"mapped\\\",[7707]],[[7707,7707],\\\"valid\\\"],[[7708,7708],\\\"mapped\\\",[7709]],[[7709,7709],\\\"valid\\\"],[[7710,7710],\\\"mapped\\\",[7711]],[[7711,7711],\\\"valid\\\"],[[7712,7712],\\\"mapped\\\",[7713]],[[7713,7713],\\\"valid\\\"],[[7714,7714],\\\"mapped\\\",[7715]],[[7715,7715],\\\"valid\\\"],[[7716,7716],\\\"mapped\\\",[7717]],[[7717,7717],\\\"valid\\\"],[[7718,7718],\\\"mapped\\\",[7719]],[[7719,7719],\\\"valid\\\"],[[7720,7720],\\\"mapped\\\",[7721]],[[7721,7721],\\\"valid\\\"],[[7722,7722],\\\"mapped\\\",[7723]],[[7723,7723],\\\"valid\\\"],[[7724,7724],\\\"mapped\\\",[7725]],[[7725,7725],\\\"valid\\\"],[[7726,7726],\\\"mapped\\\",[7727]],[[7727,7727],\\\"valid\\\"],[[7728,7728],\\\"mapped\\\",[7729]],[[7729,7729],\\\"valid\\\"],[[7730,7730],\\\"mapped\\\",[7731]],[[7731,7731],\\\"valid\\\"],[[7732,7732],\\\"mapped\\\",[7733]],[[7733,7733],\\\"valid\\\"],[[7734,7734],\\\"mapped\\\",[7735]],[[7735,7735],\\\"valid\\\"],[[7736,7736],\\\"mapped\\\",[7737]],[[7737,7737],\\\"valid\\\"],[[7738,7738],\\\"mapped\\\",[7739]],[[7739,7739],\\\"valid\\\"],[[7740,7740],\\\"mapped\\\",[7741]],[[7741,7741],\\\"valid\\\"],[[7742,7742],\\\"mapped\\\",[7743]],[[7743,7743],\\\"valid\\\"],[[7744,7744],\\\"mapped\\\",[7745]],[[7745,7745],\\\"valid\\\"],[[7746,7746],\\\"mapped\\\",[7747]],[[7747,7747],\\\"valid\\\"],[[7748,7748],\\\"mapped\\\",[7749]],[[7749,7749],\\\"valid\\\"],[[7750,7750],\\\"mapped\\\",[7751]],[[7751,7751],\\\"valid\\\"],[[7752,7752],\\\"mapped\\\",[7753]],[[7753,7753],\\\"valid\\\"],[[7754,7754],\\\"mapped\\\",[7755]],[[7755,7755],\\\"valid\\\"],[[7756,7756],\\\"mapped\\\",[7757]],[[7757,7757],\\\"valid\\\"],[[7758,7758],\\\"mapped\\\",[7759]],[[7759,7759],\\\"valid\\\"],[[7760,7760],\\\"mapped\\\",[7761]],[[7761,7761],\\\"valid\\\"],[[7762,7762],\\\"mapped\\\",[7763]],[[7763,7763],\\\"valid\\\"],[[7764,7764],\\\"mapped\\\",[7765]],[[7765,7765],\\\"valid\\\"],[[7766,7766],\\\"mapped\\\",[7767]],[[7767,7767],\\\"valid\\\"],[[7768,7768],\\\"mapped\\\",[7769]],[[7769,7769],\\\"valid\\\"],[[7770,7770],\\\"mapped\\\",[7771]],[[7771,7771],\\\"valid\\\"],[[7772,7772],\\\"mapped\\\",[7773]],[[7773,7773],\\\"valid\\\"],[[7774,7774],\\\"mapped\\\",[7775]],[[7775,7775],\\\"valid\\\"],[[7776,7776],\\\"mapped\\\",[7777]],[[7777,7777],\\\"valid\\\"],[[7778,7778],\\\"mapped\\\",[7779]],[[7779,7779],\\\"valid\\\"],[[7780,7780],\\\"mapped\\\",[7781]],[[7781,7781],\\\"valid\\\"],[[7782,7782],\\\"mapped\\\",[7783]],[[7783,7783],\\\"valid\\\"],[[7784,7784],\\\"mapped\\\",[7785]],[[7785,7785],\\\"valid\\\"],[[7786,7786],\\\"mapped\\\",[7787]],[[7787,7787],\\\"valid\\\"],[[7788,7788],\\\"mapped\\\",[7789]],[[7789,7789],\\\"valid\\\"],[[7790,7790],\\\"mapped\\\",[7791]],[[7791,7791],\\\"valid\\\"],[[7792,7792],\\\"mapped\\\",[7793]],[[7793,7793],\\\"valid\\\"],[[7794,7794],\\\"mapped\\\",[7795]],[[7795,7795],\\\"valid\\\"],[[7796,7796],\\\"mapped\\\",[7797]],[[7797,7797],\\\"valid\\\"],[[7798,7798],\\\"mapped\\\",[7799]],[[7799,7799],\\\"valid\\\"],[[7800,7800],\\\"mapped\\\",[7801]],[[7801,7801],\\\"valid\\\"],[[7802,7802],\\\"mapped\\\",[7803]],[[7803,7803],\\\"valid\\\"],[[7804,7804],\\\"mapped\\\",[7805]],[[7805,7805],\\\"valid\\\"],[[7806,7806],\\\"mapped\\\",[7807]],[[7807,7807],\\\"valid\\\"],[[7808,7808],\\\"mapped\\\",[7809]],[[7809,7809],\\\"valid\\\"],[[7810,7810],\\\"mapped\\\",[7811]],[[7811,7811],\\\"valid\\\"],[[7812,7812],\\\"mapped\\\",[7813]],[[7813,7813],\\\"valid\\\"],[[7814,7814],\\\"mapped\\\",[7815]],[[7815,7815],\\\"valid\\\"],[[7816,7816],\\\"mapped\\\",[7817]],[[7817,7817],\\\"valid\\\"],[[7818,7818],\\\"mapped\\\",[7819]],[[7819,7819],\\\"valid\\\"],[[7820,7820],\\\"mapped\\\",[7821]],[[7821,7821],\\\"valid\\\"],[[7822,7822],\\\"mapped\\\",[7823]],[[7823,7823],\\\"valid\\\"],[[7824,7824],\\\"mapped\\\",[7825]],[[7825,7825],\\\"valid\\\"],[[7826,7826],\\\"mapped\\\",[7827]],[[7827,7827],\\\"valid\\\"],[[7828,7828],\\\"mapped\\\",[7829]],[[7829,7833],\\\"valid\\\"],[[7834,7834],\\\"mapped\\\",[97,702]],[[7835,7835],\\\"mapped\\\",[7777]],[[7836,7837],\\\"valid\\\"],[[7838,7838],\\\"mapped\\\",[115,115]],[[7839,7839],\\\"valid\\\"],[[7840,7840],\\\"mapped\\\",[7841]],[[7841,7841],\\\"valid\\\"],[[7842,7842],\\\"mapped\\\",[7843]],[[7843,7843],\\\"valid\\\"],[[7844,7844],\\\"mapped\\\",[7845]],[[7845,7845],\\\"valid\\\"],[[7846,7846],\\\"mapped\\\",[7847]],[[7847,7847],\\\"valid\\\"],[[7848,7848],\\\"mapped\\\",[7849]],[[7849,7849],\\\"valid\\\"],[[7850,7850],\\\"mapped\\\",[7851]],[[7851,7851],\\\"valid\\\"],[[7852,7852],\\\"mapped\\\",[7853]],[[7853,7853],\\\"valid\\\"],[[7854,7854],\\\"mapped\\\",[7855]],[[7855,7855],\\\"valid\\\"],[[7856,7856],\\\"mapped\\\",[7857]],[[7857,7857],\\\"valid\\\"],[[7858,7858],\\\"mapped\\\",[7859]],[[7859,7859],\\\"valid\\\"],[[7860,7860],\\\"mapped\\\",[7861]],[[7861,7861],\\\"valid\\\"],[[7862,7862],\\\"mapped\\\",[7863]],[[7863,7863],\\\"valid\\\"],[[7864,7864],\\\"mapped\\\",[7865]],[[7865,7865],\\\"valid\\\"],[[7866,7866],\\\"mapped\\\",[7867]],[[7867,7867],\\\"valid\\\"],[[7868,7868],\\\"mapped\\\",[7869]],[[7869,7869],\\\"valid\\\"],[[7870,7870],\\\"mapped\\\",[7871]],[[7871,7871],\\\"valid\\\"],[[7872,7872],\\\"mapped\\\",[7873]],[[7873,7873],\\\"valid\\\"],[[7874,7874],\\\"mapped\\\",[7875]],[[7875,7875],\\\"valid\\\"],[[7876,7876],\\\"mapped\\\",[7877]],[[7877,7877],\\\"valid\\\"],[[7878,7878],\\\"mapped\\\",[7879]],[[7879,7879],\\\"valid\\\"],[[7880,7880],\\\"mapped\\\",[7881]],[[7881,7881],\\\"valid\\\"],[[7882,7882],\\\"mapped\\\",[7883]],[[7883,7883],\\\"valid\\\"],[[7884,7884],\\\"mapped\\\",[7885]],[[7885,7885],\\\"valid\\\"],[[7886,7886],\\\"mapped\\\",[7887]],[[7887,7887],\\\"valid\\\"],[[7888,7888],\\\"mapped\\\",[7889]],[[7889,7889],\\\"valid\\\"],[[7890,7890],\\\"mapped\\\",[7891]],[[7891,7891],\\\"valid\\\"],[[7892,7892],\\\"mapped\\\",[7893]],[[7893,7893],\\\"valid\\\"],[[7894,7894],\\\"mapped\\\",[7895]],[[7895,7895],\\\"valid\\\"],[[7896,7896],\\\"mapped\\\",[7897]],[[7897,7897],\\\"valid\\\"],[[7898,7898],\\\"mapped\\\",[7899]],[[7899,7899],\\\"valid\\\"],[[7900,7900],\\\"mapped\\\",[7901]],[[7901,7901],\\\"valid\\\"],[[7902,7902],\\\"mapped\\\",[7903]],[[7903,7903],\\\"valid\\\"],[[7904,7904],\\\"mapped\\\",[7905]],[[7905,7905],\\\"valid\\\"],[[7906,7906],\\\"mapped\\\",[7907]],[[7907,7907],\\\"valid\\\"],[[7908,7908],\\\"mapped\\\",[7909]],[[7909,7909],\\\"valid\\\"],[[7910,7910],\\\"mapped\\\",[7911]],[[7911,7911],\\\"valid\\\"],[[7912,7912],\\\"mapped\\\",[7913]],[[7913,7913],\\\"valid\\\"],[[7914,7914],\\\"mapped\\\",[7915]],[[7915,7915],\\\"valid\\\"],[[7916,7916],\\\"mapped\\\",[7917]],[[7917,7917],\\\"valid\\\"],[[7918,7918],\\\"mapped\\\",[7919]],[[7919,7919],\\\"valid\\\"],[[7920,7920],\\\"mapped\\\",[7921]],[[7921,7921],\\\"valid\\\"],[[7922,7922],\\\"mapped\\\",[7923]],[[7923,7923],\\\"valid\\\"],[[7924,7924],\\\"mapped\\\",[7925]],[[7925,7925],\\\"valid\\\"],[[7926,7926],\\\"mapped\\\",[7927]],[[7927,7927],\\\"valid\\\"],[[7928,7928],\\\"mapped\\\",[7929]],[[7929,7929],\\\"valid\\\"],[[7930,7930],\\\"mapped\\\",[7931]],[[7931,7931],\\\"valid\\\"],[[7932,7932],\\\"mapped\\\",[7933]],[[7933,7933],\\\"valid\\\"],[[7934,7934],\\\"mapped\\\",[7935]],[[7935,7935],\\\"valid\\\"],[[7936,7943],\\\"valid\\\"],[[7944,7944],\\\"mapped\\\",[7936]],[[7945,7945],\\\"mapped\\\",[7937]],[[7946,7946],\\\"mapped\\\",[7938]],[[7947,7947],\\\"mapped\\\",[7939]],[[7948,7948],\\\"mapped\\\",[7940]],[[7949,7949],\\\"mapped\\\",[7941]],[[7950,7950],\\\"mapped\\\",[7942]],[[7951,7951],\\\"mapped\\\",[7943]],[[7952,7957],\\\"valid\\\"],[[7958,7959],\\\"disallowed\\\"],[[7960,7960],\\\"mapped\\\",[7952]],[[7961,7961],\\\"mapped\\\",[7953]],[[7962,7962],\\\"mapped\\\",[7954]],[[7963,7963],\\\"mapped\\\",[7955]],[[7964,7964],\\\"mapped\\\",[7956]],[[7965,7965],\\\"mapped\\\",[7957]],[[7966,7967],\\\"disallowed\\\"],[[7968,7975],\\\"valid\\\"],[[7976,7976],\\\"mapped\\\",[7968]],[[7977,7977],\\\"mapped\\\",[7969]],[[7978,7978],\\\"mapped\\\",[7970]],[[7979,7979],\\\"mapped\\\",[7971]],[[7980,7980],\\\"mapped\\\",[7972]],[[7981,7981],\\\"mapped\\\",[7973]],[[7982,7982],\\\"mapped\\\",[7974]],[[7983,7983],\\\"mapped\\\",[7975]],[[7984,7991],\\\"valid\\\"],[[7992,7992],\\\"mapped\\\",[7984]],[[7993,7993],\\\"mapped\\\",[7985]],[[7994,7994],\\\"mapped\\\",[7986]],[[7995,7995],\\\"mapped\\\",[7987]],[[7996,7996],\\\"mapped\\\",[7988]],[[7997,7997],\\\"mapped\\\",[7989]],[[7998,7998],\\\"mapped\\\",[7990]],[[7999,7999],\\\"mapped\\\",[7991]],[[8000,8005],\\\"valid\\\"],[[8006,8007],\\\"disallowed\\\"],[[8008,8008],\\\"mapped\\\",[8000]],[[8009,8009],\\\"mapped\\\",[8001]],[[8010,8010],\\\"mapped\\\",[8002]],[[8011,8011],\\\"mapped\\\",[8003]],[[8012,8012],\\\"mapped\\\",[8004]],[[8013,8013],\\\"mapped\\\",[8005]],[[8014,8015],\\\"disallowed\\\"],[[8016,8023],\\\"valid\\\"],[[8024,8024],\\\"disallowed\\\"],[[8025,8025],\\\"mapped\\\",[8017]],[[8026,8026],\\\"disallowed\\\"],[[8027,8027],\\\"mapped\\\",[8019]],[[8028,8028],\\\"disallowed\\\"],[[8029,8029],\\\"mapped\\\",[8021]],[[8030,8030],\\\"disallowed\\\"],[[8031,8031],\\\"mapped\\\",[8023]],[[8032,8039],\\\"valid\\\"],[[8040,8040],\\\"mapped\\\",[8032]],[[8041,8041],\\\"mapped\\\",[8033]],[[8042,8042],\\\"mapped\\\",[8034]],[[8043,8043],\\\"mapped\\\",[8035]],[[8044,8044],\\\"mapped\\\",[8036]],[[8045,8045],\\\"mapped\\\",[8037]],[[8046,8046],\\\"mapped\\\",[8038]],[[8047,8047],\\\"mapped\\\",[8039]],[[8048,8048],\\\"valid\\\"],[[8049,8049],\\\"mapped\\\",[940]],[[8050,8050],\\\"valid\\\"],[[8051,8051],\\\"mapped\\\",[941]],[[8052,8052],\\\"valid\\\"],[[8053,8053],\\\"mapped\\\",[942]],[[8054,8054],\\\"valid\\\"],[[8055,8055],\\\"mapped\\\",[943]],[[8056,8056],\\\"valid\\\"],[[8057,8057],\\\"mapped\\\",[972]],[[8058,8058],\\\"valid\\\"],[[8059,8059],\\\"mapped\\\",[973]],[[8060,8060],\\\"valid\\\"],[[8061,8061],\\\"mapped\\\",[974]],[[8062,8063],\\\"disallowed\\\"],[[8064,8064],\\\"mapped\\\",[7936,953]],[[8065,8065],\\\"mapped\\\",[7937,953]],[[8066,8066],\\\"mapped\\\",[7938,953]],[[8067,8067],\\\"mapped\\\",[7939,953]],[[8068,8068],\\\"mapped\\\",[7940,953]],[[8069,8069],\\\"mapped\\\",[7941,953]],[[8070,8070],\\\"mapped\\\",[7942,953]],[[8071,8071],\\\"mapped\\\",[7943,953]],[[8072,8072],\\\"mapped\\\",[7936,953]],[[8073,8073],\\\"mapped\\\",[7937,953]],[[8074,8074],\\\"mapped\\\",[7938,953]],[[8075,8075],\\\"mapped\\\",[7939,953]],[[8076,8076],\\\"mapped\\\",[7940,953]],[[8077,8077],\\\"mapped\\\",[7941,953]],[[8078,8078],\\\"mapped\\\",[7942,953]],[[8079,8079],\\\"mapped\\\",[7943,953]],[[8080,8080],\\\"mapped\\\",[7968,953]],[[8081,8081],\\\"mapped\\\",[7969,953]],[[8082,8082],\\\"mapped\\\",[7970,953]],[[8083,8083],\\\"mapped\\\",[7971,953]],[[8084,8084],\\\"mapped\\\",[7972,953]],[[8085,8085],\\\"mapped\\\",[7973,953]],[[8086,8086],\\\"mapped\\\",[7974,953]],[[8087,8087],\\\"mapped\\\",[7975,953]],[[8088,8088],\\\"mapped\\\",[7968,953]],[[8089,8089],\\\"mapped\\\",[7969,953]],[[8090,8090],\\\"mapped\\\",[7970,953]],[[8091,8091],\\\"mapped\\\",[7971,953]],[[8092,8092],\\\"mapped\\\",[7972,953]],[[8093,8093],\\\"mapped\\\",[7973,953]],[[8094,8094],\\\"mapped\\\",[7974,953]],[[8095,8095],\\\"mapped\\\",[7975,953]],[[8096,8096],\\\"mapped\\\",[8032,953]],[[8097,8097],\\\"mapped\\\",[8033,953]],[[8098,8098],\\\"mapped\\\",[8034,953]],[[8099,8099],\\\"mapped\\\",[8035,953]],[[8100,8100],\\\"mapped\\\",[8036,953]],[[8101,8101],\\\"mapped\\\",[8037,953]],[[8102,8102],\\\"mapped\\\",[8038,953]],[[8103,8103],\\\"mapped\\\",[8039,953]],[[8104,8104],\\\"mapped\\\",[8032,953]],[[8105,8105],\\\"mapped\\\",[8033,953]],[[8106,8106],\\\"mapped\\\",[8034,953]],[[8107,8107],\\\"mapped\\\",[8035,953]],[[8108,8108],\\\"mapped\\\",[8036,953]],[[8109,8109],\\\"mapped\\\",[8037,953]],[[8110,8110],\\\"mapped\\\",[8038,953]],[[8111,8111],\\\"mapped\\\",[8039,953]],[[8112,8113],\\\"valid\\\"],[[8114,8114],\\\"mapped\\\",[8048,953]],[[8115,8115],\\\"mapped\\\",[945,953]],[[8116,8116],\\\"mapped\\\",[940,953]],[[8117,8117],\\\"disallowed\\\"],[[8118,8118],\\\"valid\\\"],[[8119,8119],\\\"mapped\\\",[8118,953]],[[8120,8120],\\\"mapped\\\",[8112]],[[8121,8121],\\\"mapped\\\",[8113]],[[8122,8122],\\\"mapped\\\",[8048]],[[8123,8123],\\\"mapped\\\",[940]],[[8124,8124],\\\"mapped\\\",[945,953]],[[8125,8125],\\\"disallowed_STD3_mapped\\\",[32,787]],[[8126,8126],\\\"mapped\\\",[953]],[[8127,8127],\\\"disallowed_STD3_mapped\\\",[32,787]],[[8128,8128],\\\"disallowed_STD3_mapped\\\",[32,834]],[[8129,8129],\\\"disallowed_STD3_mapped\\\",[32,776,834]],[[8130,8130],\\\"mapped\\\",[8052,953]],[[8131,8131],\\\"mapped\\\",[951,953]],[[8132,8132],\\\"mapped\\\",[942,953]],[[8133,8133],\\\"disallowed\\\"],[[8134,8134],\\\"valid\\\"],[[8135,8135],\\\"mapped\\\",[8134,953]],[[8136,8136],\\\"mapped\\\",[8050]],[[8137,8137],\\\"mapped\\\",[941]],[[8138,8138],\\\"mapped\\\",[8052]],[[8139,8139],\\\"mapped\\\",[942]],[[8140,8140],\\\"mapped\\\",[951,953]],[[8141,8141],\\\"disallowed_STD3_mapped\\\",[32,787,768]],[[8142,8142],\\\"disallowed_STD3_mapped\\\",[32,787,769]],[[8143,8143],\\\"disallowed_STD3_mapped\\\",[32,787,834]],[[8144,8146],\\\"valid\\\"],[[8147,8147],\\\"mapped\\\",[912]],[[8148,8149],\\\"disallowed\\\"],[[8150,8151],\\\"valid\\\"],[[8152,8152],\\\"mapped\\\",[8144]],[[8153,8153],\\\"mapped\\\",[8145]],[[8154,8154],\\\"mapped\\\",[8054]],[[8155,8155],\\\"mapped\\\",[943]],[[8156,8156],\\\"disallowed\\\"],[[8157,8157],\\\"disallowed_STD3_mapped\\\",[32,788,768]],[[8158,8158],\\\"disallowed_STD3_mapped\\\",[32,788,769]],[[8159,8159],\\\"disallowed_STD3_mapped\\\",[32,788,834]],[[8160,8162],\\\"valid\\\"],[[8163,8163],\\\"mapped\\\",[944]],[[8164,8167],\\\"valid\\\"],[[8168,8168],\\\"mapped\\\",[8160]],[[8169,8169],\\\"mapped\\\",[8161]],[[8170,8170],\\\"mapped\\\",[8058]],[[8171,8171],\\\"mapped\\\",[973]],[[8172,8172],\\\"mapped\\\",[8165]],[[8173,8173],\\\"disallowed_STD3_mapped\\\",[32,776,768]],[[8174,8174],\\\"disallowed_STD3_mapped\\\",[32,776,769]],[[8175,8175],\\\"disallowed_STD3_mapped\\\",[96]],[[8176,8177],\\\"disallowed\\\"],[[8178,8178],\\\"mapped\\\",[8060,953]],[[8179,8179],\\\"mapped\\\",[969,953]],[[8180,8180],\\\"mapped\\\",[974,953]],[[8181,8181],\\\"disallowed\\\"],[[8182,8182],\\\"valid\\\"],[[8183,8183],\\\"mapped\\\",[8182,953]],[[8184,8184],\\\"mapped\\\",[8056]],[[8185,8185],\\\"mapped\\\",[972]],[[8186,8186],\\\"mapped\\\",[8060]],[[8187,8187],\\\"mapped\\\",[974]],[[8188,8188],\\\"mapped\\\",[969,953]],[[8189,8189],\\\"disallowed_STD3_mapped\\\",[32,769]],[[8190,8190],\\\"disallowed_STD3_mapped\\\",[32,788]],[[8191,8191],\\\"disallowed\\\"],[[8192,8202],\\\"disallowed_STD3_mapped\\\",[32]],[[8203,8203],\\\"ignored\\\"],[[8204,8205],\\\"deviation\\\",[]],[[8206,8207],\\\"disallowed\\\"],[[8208,8208],\\\"valid\\\",[],\\\"NV8\\\"],[[8209,8209],\\\"mapped\\\",[8208]],[[8210,8214],\\\"valid\\\",[],\\\"NV8\\\"],[[8215,8215],\\\"disallowed_STD3_mapped\\\",[32,819]],[[8216,8227],\\\"valid\\\",[],\\\"NV8\\\"],[[8228,8230],\\\"disallowed\\\"],[[8231,8231],\\\"valid\\\",[],\\\"NV8\\\"],[[8232,8238],\\\"disallowed\\\"],[[8239,8239],\\\"disallowed_STD3_mapped\\\",[32]],[[8240,8242],\\\"valid\\\",[],\\\"NV8\\\"],[[8243,8243],\\\"mapped\\\",[8242,8242]],[[8244,8244],\\\"mapped\\\",[8242,8242,8242]],[[8245,8245],\\\"valid\\\",[],\\\"NV8\\\"],[[8246,8246],\\\"mapped\\\",[8245,8245]],[[8247,8247],\\\"mapped\\\",[8245,8245,8245]],[[8248,8251],\\\"valid\\\",[],\\\"NV8\\\"],[[8252,8252],\\\"disallowed_STD3_mapped\\\",[33,33]],[[8253,8253],\\\"valid\\\",[],\\\"NV8\\\"],[[8254,8254],\\\"disallowed_STD3_mapped\\\",[32,773]],[[8255,8262],\\\"valid\\\",[],\\\"NV8\\\"],[[8263,8263],\\\"disallowed_STD3_mapped\\\",[63,63]],[[8264,8264],\\\"disallowed_STD3_mapped\\\",[63,33]],[[8265,8265],\\\"disallowed_STD3_mapped\\\",[33,63]],[[8266,8269],\\\"valid\\\",[],\\\"NV8\\\"],[[8270,8274],\\\"valid\\\",[],\\\"NV8\\\"],[[8275,8276],\\\"valid\\\",[],\\\"NV8\\\"],[[8277,8278],\\\"valid\\\",[],\\\"NV8\\\"],[[8279,8279],\\\"mapped\\\",[8242,8242,8242,8242]],[[8280,8286],\\\"valid\\\",[],\\\"NV8\\\"],[[8287,8287],\\\"disallowed_STD3_mapped\\\",[32]],[[8288,8288],\\\"ignored\\\"],[[8289,8291],\\\"disallowed\\\"],[[8292,8292],\\\"ignored\\\"],[[8293,8293],\\\"disallowed\\\"],[[8294,8297],\\\"disallowed\\\"],[[8298,8303],\\\"disallowed\\\"],[[8304,8304],\\\"mapped\\\",[48]],[[8305,8305],\\\"mapped\\\",[105]],[[8306,8307],\\\"disallowed\\\"],[[8308,8308],\\\"mapped\\\",[52]],[[8309,8309],\\\"mapped\\\",[53]],[[8310,8310],\\\"mapped\\\",[54]],[[8311,8311],\\\"mapped\\\",[55]],[[8312,8312],\\\"mapped\\\",[56]],[[8313,8313],\\\"mapped\\\",[57]],[[8314,8314],\\\"disallowed_STD3_mapped\\\",[43]],[[8315,8315],\\\"mapped\\\",[8722]],[[8316,8316],\\\"disallowed_STD3_mapped\\\",[61]],[[8317,8317],\\\"disallowed_STD3_mapped\\\",[40]],[[8318,8318],\\\"disallowed_STD3_mapped\\\",[41]],[[8319,8319],\\\"mapped\\\",[110]],[[8320,8320],\\\"mapped\\\",[48]],[[8321,8321],\\\"mapped\\\",[49]],[[8322,8322],\\\"mapped\\\",[50]],[[8323,8323],\\\"mapped\\\",[51]],[[8324,8324],\\\"mapped\\\",[52]],[[8325,8325],\\\"mapped\\\",[53]],[[8326,8326],\\\"mapped\\\",[54]],[[8327,8327],\\\"mapped\\\",[55]],[[8328,8328],\\\"mapped\\\",[56]],[[8329,8329],\\\"mapped\\\",[57]],[[8330,8330],\\\"disallowed_STD3_mapped\\\",[43]],[[8331,8331],\\\"mapped\\\",[8722]],[[8332,8332],\\\"disallowed_STD3_mapped\\\",[61]],[[8333,8333],\\\"disallowed_STD3_mapped\\\",[40]],[[8334,8334],\\\"disallowed_STD3_mapped\\\",[41]],[[8335,8335],\\\"disallowed\\\"],[[8336,8336],\\\"mapped\\\",[97]],[[8337,8337],\\\"mapped\\\",[101]],[[8338,8338],\\\"mapped\\\",[111]],[[8339,8339],\\\"mapped\\\",[120]],[[8340,8340],\\\"mapped\\\",[601]],[[8341,8341],\\\"mapped\\\",[104]],[[8342,8342],\\\"mapped\\\",[107]],[[8343,8343],\\\"mapped\\\",[108]],[[8344,8344],\\\"mapped\\\",[109]],[[8345,8345],\\\"mapped\\\",[110]],[[8346,8346],\\\"mapped\\\",[112]],[[8347,8347],\\\"mapped\\\",[115]],[[8348,8348],\\\"mapped\\\",[116]],[[8349,8351],\\\"disallowed\\\"],[[8352,8359],\\\"valid\\\",[],\\\"NV8\\\"],[[8360,8360],\\\"mapped\\\",[114,115]],[[8361,8362],\\\"valid\\\",[],\\\"NV8\\\"],[[8363,8363],\\\"valid\\\",[],\\\"NV8\\\"],[[8364,8364],\\\"valid\\\",[],\\\"NV8\\\"],[[8365,8367],\\\"valid\\\",[],\\\"NV8\\\"],[[8368,8369],\\\"valid\\\",[],\\\"NV8\\\"],[[8370,8373],\\\"valid\\\",[],\\\"NV8\\\"],[[8374,8376],\\\"valid\\\",[],\\\"NV8\\\"],[[8377,8377],\\\"valid\\\",[],\\\"NV8\\\"],[[8378,8378],\\\"valid\\\",[],\\\"NV8\\\"],[[8379,8381],\\\"valid\\\",[],\\\"NV8\\\"],[[8382,8382],\\\"valid\\\",[],\\\"NV8\\\"],[[8383,8399],\\\"disallowed\\\"],[[8400,8417],\\\"valid\\\",[],\\\"NV8\\\"],[[8418,8419],\\\"valid\\\",[],\\\"NV8\\\"],[[8420,8426],\\\"valid\\\",[],\\\"NV8\\\"],[[8427,8427],\\\"valid\\\",[],\\\"NV8\\\"],[[8428,8431],\\\"valid\\\",[],\\\"NV8\\\"],[[8432,8432],\\\"valid\\\",[],\\\"NV8\\\"],[[8433,8447],\\\"disallowed\\\"],[[8448,8448],\\\"disallowed_STD3_mapped\\\",[97,47,99]],[[8449,8449],\\\"disallowed_STD3_mapped\\\",[97,47,115]],[[8450,8450],\\\"mapped\\\",[99]],[[8451,8451],\\\"mapped\\\",[176,99]],[[8452,8452],\\\"valid\\\",[],\\\"NV8\\\"],[[8453,8453],\\\"disallowed_STD3_mapped\\\",[99,47,111]],[[8454,8454],\\\"disallowed_STD3_mapped\\\",[99,47,117]],[[8455,8455],\\\"mapped\\\",[603]],[[8456,8456],\\\"valid\\\",[],\\\"NV8\\\"],[[8457,8457],\\\"mapped\\\",[176,102]],[[8458,8458],\\\"mapped\\\",[103]],[[8459,8462],\\\"mapped\\\",[104]],[[8463,8463],\\\"mapped\\\",[295]],[[8464,8465],\\\"mapped\\\",[105]],[[8466,8467],\\\"mapped\\\",[108]],[[8468,8468],\\\"valid\\\",[],\\\"NV8\\\"],[[8469,8469],\\\"mapped\\\",[110]],[[8470,8470],\\\"mapped\\\",[110,111]],[[8471,8472],\\\"valid\\\",[],\\\"NV8\\\"],[[8473,8473],\\\"mapped\\\",[112]],[[8474,8474],\\\"mapped\\\",[113]],[[8475,8477],\\\"mapped\\\",[114]],[[8478,8479],\\\"valid\\\",[],\\\"NV8\\\"],[[8480,8480],\\\"mapped\\\",[115,109]],[[8481,8481],\\\"mapped\\\",[116,101,108]],[[8482,8482],\\\"mapped\\\",[116,109]],[[8483,8483],\\\"valid\\\",[],\\\"NV8\\\"],[[8484,8484],\\\"mapped\\\",[122]],[[8485,8485],\\\"valid\\\",[],\\\"NV8\\\"],[[8486,8486],\\\"mapped\\\",[969]],[[8487,8487],\\\"valid\\\",[],\\\"NV8\\\"],[[8488,8488],\\\"mapped\\\",[122]],[[8489,8489],\\\"valid\\\",[],\\\"NV8\\\"],[[8490,8490],\\\"mapped\\\",[107]],[[8491,8491],\\\"mapped\\\",[229]],[[8492,8492],\\\"mapped\\\",[98]],[[8493,8493],\\\"mapped\\\",[99]],[[8494,8494],\\\"valid\\\",[],\\\"NV8\\\"],[[8495,8496],\\\"mapped\\\",[101]],[[8497,8497],\\\"mapped\\\",[102]],[[8498,8498],\\\"disallowed\\\"],[[8499,8499],\\\"mapped\\\",[109]],[[8500,8500],\\\"mapped\\\",[111]],[[8501,8501],\\\"mapped\\\",[1488]],[[8502,8502],\\\"mapped\\\",[1489]],[[8503,8503],\\\"mapped\\\",[1490]],[[8504,8504],\\\"mapped\\\",[1491]],[[8505,8505],\\\"mapped\\\",[105]],[[8506,8506],\\\"valid\\\",[],\\\"NV8\\\"],[[8507,8507],\\\"mapped\\\",[102,97,120]],[[8508,8508],\\\"mapped\\\",[960]],[[8509,8510],\\\"mapped\\\",[947]],[[8511,8511],\\\"mapped\\\",[960]],[[8512,8512],\\\"mapped\\\",[8721]],[[8513,8516],\\\"valid\\\",[],\\\"NV8\\\"],[[8517,8518],\\\"mapped\\\",[100]],[[8519,8519],\\\"mapped\\\",[101]],[[8520,8520],\\\"mapped\\\",[105]],[[8521,8521],\\\"mapped\\\",[106]],[[8522,8523],\\\"valid\\\",[],\\\"NV8\\\"],[[8524,8524],\\\"valid\\\",[],\\\"NV8\\\"],[[8525,8525],\\\"valid\\\",[],\\\"NV8\\\"],[[8526,8526],\\\"valid\\\"],[[8527,8527],\\\"valid\\\",[],\\\"NV8\\\"],[[8528,8528],\\\"mapped\\\",[49,8260,55]],[[8529,8529],\\\"mapped\\\",[49,8260,57]],[[8530,8530],\\\"mapped\\\",[49,8260,49,48]],[[8531,8531],\\\"mapped\\\",[49,8260,51]],[[8532,8532],\\\"mapped\\\",[50,8260,51]],[[8533,8533],\\\"mapped\\\",[49,8260,53]],[[8534,8534],\\\"mapped\\\",[50,8260,53]],[[8535,8535],\\\"mapped\\\",[51,8260,53]],[[8536,8536],\\\"mapped\\\",[52,8260,53]],[[8537,8537],\\\"mapped\\\",[49,8260,54]],[[8538,8538],\\\"mapped\\\",[53,8260,54]],[[8539,8539],\\\"mapped\\\",[49,8260,56]],[[8540,8540],\\\"mapped\\\",[51,8260,56]],[[8541,8541],\\\"mapped\\\",[53,8260,56]],[[8542,8542],\\\"mapped\\\",[55,8260,56]],[[8543,8543],\\\"mapped\\\",[49,8260]],[[8544,8544],\\\"mapped\\\",[105]],[[8545,8545],\\\"mapped\\\",[105,105]],[[8546,8546],\\\"mapped\\\",[105,105,105]],[[8547,8547],\\\"mapped\\\",[105,118]],[[8548,8548],\\\"mapped\\\",[118]],[[8549,8549],\\\"mapped\\\",[118,105]],[[8550,8550],\\\"mapped\\\",[118,105,105]],[[8551,8551],\\\"mapped\\\",[118,105,105,105]],[[8552,8552],\\\"mapped\\\",[105,120]],[[8553,8553],\\\"mapped\\\",[120]],[[8554,8554],\\\"mapped\\\",[120,105]],[[8555,8555],\\\"mapped\\\",[120,105,105]],[[8556,8556],\\\"mapped\\\",[108]],[[8557,8557],\\\"mapped\\\",[99]],[[8558,8558],\\\"mapped\\\",[100]],[[8559,8559],\\\"mapped\\\",[109]],[[8560,8560],\\\"mapped\\\",[105]],[[8561,8561],\\\"mapped\\\",[105,105]],[[8562,8562],\\\"mapped\\\",[105,105,105]],[[8563,8563],\\\"mapped\\\",[105,118]],[[8564,8564],\\\"mapped\\\",[118]],[[8565,8565],\\\"mapped\\\",[118,105]],[[8566,8566],\\\"mapped\\\",[118,105,105]],[[8567,8567],\\\"mapped\\\",[118,105,105,105]],[[8568,8568],\\\"mapped\\\",[105,120]],[[8569,8569],\\\"mapped\\\",[120]],[[8570,8570],\\\"mapped\\\",[120,105]],[[8571,8571],\\\"mapped\\\",[120,105,105]],[[8572,8572],\\\"mapped\\\",[108]],[[8573,8573],\\\"mapped\\\",[99]],[[8574,8574],\\\"mapped\\\",[100]],[[8575,8575],\\\"mapped\\\",[109]],[[8576,8578],\\\"valid\\\",[],\\\"NV8\\\"],[[8579,8579],\\\"disallowed\\\"],[[8580,8580],\\\"valid\\\"],[[8581,8584],\\\"valid\\\",[],\\\"NV8\\\"],[[8585,8585],\\\"mapped\\\",[48,8260,51]],[[8586,8587],\\\"valid\\\",[],\\\"NV8\\\"],[[8588,8591],\\\"disallowed\\\"],[[8592,8682],\\\"valid\\\",[],\\\"NV8\\\"],[[8683,8691],\\\"valid\\\",[],\\\"NV8\\\"],[[8692,8703],\\\"valid\\\",[],\\\"NV8\\\"],[[8704,8747],\\\"valid\\\",[],\\\"NV8\\\"],[[8748,8748],\\\"mapped\\\",[8747,8747]],[[8749,8749],\\\"mapped\\\",[8747,8747,8747]],[[8750,8750],\\\"valid\\\",[],\\\"NV8\\\"],[[8751,8751],\\\"mapped\\\",[8750,8750]],[[8752,8752],\\\"mapped\\\",[8750,8750,8750]],[[8753,8799],\\\"valid\\\",[],\\\"NV8\\\"],[[8800,8800],\\\"disallowed_STD3_valid\\\"],[[8801,8813],\\\"valid\\\",[],\\\"NV8\\\"],[[8814,8815],\\\"disallowed_STD3_valid\\\"],[[8816,8945],\\\"valid\\\",[],\\\"NV8\\\"],[[8946,8959],\\\"valid\\\",[],\\\"NV8\\\"],[[8960,8960],\\\"valid\\\",[],\\\"NV8\\\"],[[8961,8961],\\\"valid\\\",[],\\\"NV8\\\"],[[8962,9000],\\\"valid\\\",[],\\\"NV8\\\"],[[9001,9001],\\\"mapped\\\",[12296]],[[9002,9002],\\\"mapped\\\",[12297]],[[9003,9082],\\\"valid\\\",[],\\\"NV8\\\"],[[9083,9083],\\\"valid\\\",[],\\\"NV8\\\"],[[9084,9084],\\\"valid\\\",[],\\\"NV8\\\"],[[9085,9114],\\\"valid\\\",[],\\\"NV8\\\"],[[9115,9166],\\\"valid\\\",[],\\\"NV8\\\"],[[9167,9168],\\\"valid\\\",[],\\\"NV8\\\"],[[9169,9179],\\\"valid\\\",[],\\\"NV8\\\"],[[9180,9191],\\\"valid\\\",[],\\\"NV8\\\"],[[9192,9192],\\\"valid\\\",[],\\\"NV8\\\"],[[9193,9203],\\\"valid\\\",[],\\\"NV8\\\"],[[9204,9210],\\\"valid\\\",[],\\\"NV8\\\"],[[9211,9215],\\\"disallowed\\\"],[[9216,9252],\\\"valid\\\",[],\\\"NV8\\\"],[[9253,9254],\\\"valid\\\",[],\\\"NV8\\\"],[[9255,9279],\\\"disallowed\\\"],[[9280,9290],\\\"valid\\\",[],\\\"NV8\\\"],[[9291,9311],\\\"disallowed\\\"],[[9312,9312],\\\"mapped\\\",[49]],[[9313,9313],\\\"mapped\\\",[50]],[[9314,9314],\\\"mapped\\\",[51]],[[9315,9315],\\\"mapped\\\",[52]],[[9316,9316],\\\"mapped\\\",[53]],[[9317,9317],\\\"mapped\\\",[54]],[[9318,9318],\\\"mapped\\\",[55]],[[9319,9319],\\\"mapped\\\",[56]],[[9320,9320],\\\"mapped\\\",[57]],[[9321,9321],\\\"mapped\\\",[49,48]],[[9322,9322],\\\"mapped\\\",[49,49]],[[9323,9323],\\\"mapped\\\",[49,50]],[[9324,9324],\\\"mapped\\\",[49,51]],[[9325,9325],\\\"mapped\\\",[49,52]],[[9326,9326],\\\"mapped\\\",[49,53]],[[9327,9327],\\\"mapped\\\",[49,54]],[[9328,9328],\\\"mapped\\\",[49,55]],[[9329,9329],\\\"mapped\\\",[49,56]],[[9330,9330],\\\"mapped\\\",[49,57]],[[9331,9331],\\\"mapped\\\",[50,48]],[[9332,9332],\\\"disallowed_STD3_mapped\\\",[40,49,41]],[[9333,9333],\\\"disallowed_STD3_mapped\\\",[40,50,41]],[[9334,9334],\\\"disallowed_STD3_mapped\\\",[40,51,41]],[[9335,9335],\\\"disallowed_STD3_mapped\\\",[40,52,41]],[[9336,9336],\\\"disallowed_STD3_mapped\\\",[40,53,41]],[[9337,9337],\\\"disallowed_STD3_mapped\\\",[40,54,41]],[[9338,9338],\\\"disallowed_STD3_mapped\\\",[40,55,41]],[[9339,9339],\\\"disallowed_STD3_mapped\\\",[40,56,41]],[[9340,9340],\\\"disallowed_STD3_mapped\\\",[40,57,41]],[[9341,9341],\\\"disallowed_STD3_mapped\\\",[40,49,48,41]],[[9342,9342],\\\"disallowed_STD3_mapped\\\",[40,49,49,41]],[[9343,9343],\\\"disallowed_STD3_mapped\\\",[40,49,50,41]],[[9344,9344],\\\"disallowed_STD3_mapped\\\",[40,49,51,41]],[[9345,9345],\\\"disallowed_STD3_mapped\\\",[40,49,52,41]],[[9346,9346],\\\"disallowed_STD3_mapped\\\",[40,49,53,41]],[[9347,9347],\\\"disallowed_STD3_mapped\\\",[40,49,54,41]],[[9348,9348],\\\"disallowed_STD3_mapped\\\",[40,49,55,41]],[[9349,9349],\\\"disallowed_STD3_mapped\\\",[40,49,56,41]],[[9350,9350],\\\"disallowed_STD3_mapped\\\",[40,49,57,41]],[[9351,9351],\\\"disallowed_STD3_mapped\\\",[40,50,48,41]],[[9352,9371],\\\"disallowed\\\"],[[9372,9372],\\\"disallowed_STD3_mapped\\\",[40,97,41]],[[9373,9373],\\\"disallowed_STD3_mapped\\\",[40,98,41]],[[9374,9374],\\\"disallowed_STD3_mapped\\\",[40,99,41]],[[9375,9375],\\\"disallowed_STD3_mapped\\\",[40,100,41]],[[9376,9376],\\\"disallowed_STD3_mapped\\\",[40,101,41]],[[9377,9377],\\\"disallowed_STD3_mapped\\\",[40,102,41]],[[9378,9378],\\\"disallowed_STD3_mapped\\\",[40,103,41]],[[9379,9379],\\\"disallowed_STD3_mapped\\\",[40,104,41]],[[9380,9380],\\\"disallowed_STD3_mapped\\\",[40,105,41]],[[9381,9381],\\\"disallowed_STD3_mapped\\\",[40,106,41]],[[9382,9382],\\\"disallowed_STD3_mapped\\\",[40,107,41]],[[9383,9383],\\\"disallowed_STD3_mapped\\\",[40,108,41]],[[9384,9384],\\\"disallowed_STD3_mapped\\\",[40,109,41]],[[9385,9385],\\\"disallowed_STD3_mapped\\\",[40,110,41]],[[9386,9386],\\\"disallowed_STD3_mapped\\\",[40,111,41]],[[9387,9387],\\\"disallowed_STD3_mapped\\\",[40,112,41]],[[9388,9388],\\\"disallowed_STD3_mapped\\\",[40,113,41]],[[9389,9389],\\\"disallowed_STD3_mapped\\\",[40,114,41]],[[9390,9390],\\\"disallowed_STD3_mapped\\\",[40,115,41]],[[9391,9391],\\\"disallowed_STD3_mapped\\\",[40,116,41]],[[9392,9392],\\\"disallowed_STD3_mapped\\\",[40,117,41]],[[9393,9393],\\\"disallowed_STD3_mapped\\\",[40,118,41]],[[9394,9394],\\\"disallowed_STD3_mapped\\\",[40,119,41]],[[9395,9395],\\\"disallowed_STD3_mapped\\\",[40,120,41]],[[9396,9396],\\\"disallowed_STD3_mapped\\\",[40,121,41]],[[9397,9397],\\\"disallowed_STD3_mapped\\\",[40,122,41]],[[9398,9398],\\\"mapped\\\",[97]],[[9399,9399],\\\"mapped\\\",[98]],[[9400,9400],\\\"mapped\\\",[99]],[[9401,9401],\\\"mapped\\\",[100]],[[9402,9402],\\\"mapped\\\",[101]],[[9403,9403],\\\"mapped\\\",[102]],[[9404,9404],\\\"mapped\\\",[103]],[[9405,9405],\\\"mapped\\\",[104]],[[9406,9406],\\\"mapped\\\",[105]],[[9407,9407],\\\"mapped\\\",[106]],[[9408,9408],\\\"mapped\\\",[107]],[[9409,9409],\\\"mapped\\\",[108]],[[9410,9410],\\\"mapped\\\",[109]],[[9411,9411],\\\"mapped\\\",[110]],[[9412,9412],\\\"mapped\\\",[111]],[[9413,9413],\\\"mapped\\\",[112]],[[9414,9414],\\\"mapped\\\",[113]],[[9415,9415],\\\"mapped\\\",[114]],[[9416,9416],\\\"mapped\\\",[115]],[[9417,9417],\\\"mapped\\\",[116]],[[9418,9418],\\\"mapped\\\",[117]],[[9419,9419],\\\"mapped\\\",[118]],[[9420,9420],\\\"mapped\\\",[119]],[[9421,9421],\\\"mapped\\\",[120]],[[9422,9422],\\\"mapped\\\",[121]],[[9423,9423],\\\"mapped\\\",[122]],[[9424,9424],\\\"mapped\\\",[97]],[[9425,9425],\\\"mapped\\\",[98]],[[9426,9426],\\\"mapped\\\",[99]],[[9427,9427],\\\"mapped\\\",[100]],[[9428,9428],\\\"mapped\\\",[101]],[[9429,9429],\\\"mapped\\\",[102]],[[9430,9430],\\\"mapped\\\",[103]],[[9431,9431],\\\"mapped\\\",[104]],[[9432,9432],\\\"mapped\\\",[105]],[[9433,9433],\\\"mapped\\\",[106]],[[9434,9434],\\\"mapped\\\",[107]],[[9435,9435],\\\"mapped\\\",[108]],[[9436,9436],\\\"mapped\\\",[109]],[[9437,9437],\\\"mapped\\\",[110]],[[9438,9438],\\\"mapped\\\",[111]],[[9439,9439],\\\"mapped\\\",[112]],[[9440,9440],\\\"mapped\\\",[113]],[[9441,9441],\\\"mapped\\\",[114]],[[9442,9442],\\\"mapped\\\",[115]],[[9443,9443],\\\"mapped\\\",[116]],[[9444,9444],\\\"mapped\\\",[117]],[[9445,9445],\\\"mapped\\\",[118]],[[9446,9446],\\\"mapped\\\",[119]],[[9447,9447],\\\"mapped\\\",[120]],[[9448,9448],\\\"mapped\\\",[121]],[[9449,9449],\\\"mapped\\\",[122]],[[9450,9450],\\\"mapped\\\",[48]],[[9451,9470],\\\"valid\\\",[],\\\"NV8\\\"],[[9471,9471],\\\"valid\\\",[],\\\"NV8\\\"],[[9472,9621],\\\"valid\\\",[],\\\"NV8\\\"],[[9622,9631],\\\"valid\\\",[],\\\"NV8\\\"],[[9632,9711],\\\"valid\\\",[],\\\"NV8\\\"],[[9712,9719],\\\"valid\\\",[],\\\"NV8\\\"],[[9720,9727],\\\"valid\\\",[],\\\"NV8\\\"],[[9728,9747],\\\"valid\\\",[],\\\"NV8\\\"],[[9748,9749],\\\"valid\\\",[],\\\"NV8\\\"],[[9750,9751],\\\"valid\\\",[],\\\"NV8\\\"],[[9752,9752],\\\"valid\\\",[],\\\"NV8\\\"],[[9753,9753],\\\"valid\\\",[],\\\"NV8\\\"],[[9754,9839],\\\"valid\\\",[],\\\"NV8\\\"],[[9840,9841],\\\"valid\\\",[],\\\"NV8\\\"],[[9842,9853],\\\"valid\\\",[],\\\"NV8\\\"],[[9854,9855],\\\"valid\\\",[],\\\"NV8\\\"],[[9856,9865],\\\"valid\\\",[],\\\"NV8\\\"],[[9866,9873],\\\"valid\\\",[],\\\"NV8\\\"],[[9874,9884],\\\"valid\\\",[],\\\"NV8\\\"],[[9885,9885],\\\"valid\\\",[],\\\"NV8\\\"],[[9886,9887],\\\"valid\\\",[],\\\"NV8\\\"],[[9888,9889],\\\"valid\\\",[],\\\"NV8\\\"],[[9890,9905],\\\"valid\\\",[],\\\"NV8\\\"],[[9906,9906],\\\"valid\\\",[],\\\"NV8\\\"],[[9907,9916],\\\"valid\\\",[],\\\"NV8\\\"],[[9917,9919],\\\"valid\\\",[],\\\"NV8\\\"],[[9920,9923],\\\"valid\\\",[],\\\"NV8\\\"],[[9924,9933],\\\"valid\\\",[],\\\"NV8\\\"],[[9934,9934],\\\"valid\\\",[],\\\"NV8\\\"],[[9935,9953],\\\"valid\\\",[],\\\"NV8\\\"],[[9954,9954],\\\"valid\\\",[],\\\"NV8\\\"],[[9955,9955],\\\"valid\\\",[],\\\"NV8\\\"],[[9956,9959],\\\"valid\\\",[],\\\"NV8\\\"],[[9960,9983],\\\"valid\\\",[],\\\"NV8\\\"],[[9984,9984],\\\"valid\\\",[],\\\"NV8\\\"],[[9985,9988],\\\"valid\\\",[],\\\"NV8\\\"],[[9989,9989],\\\"valid\\\",[],\\\"NV8\\\"],[[9990,9993],\\\"valid\\\",[],\\\"NV8\\\"],[[9994,9995],\\\"valid\\\",[],\\\"NV8\\\"],[[9996,10023],\\\"valid\\\",[],\\\"NV8\\\"],[[10024,10024],\\\"valid\\\",[],\\\"NV8\\\"],[[10025,10059],\\\"valid\\\",[],\\\"NV8\\\"],[[10060,10060],\\\"valid\\\",[],\\\"NV8\\\"],[[10061,10061],\\\"valid\\\",[],\\\"NV8\\\"],[[10062,10062],\\\"valid\\\",[],\\\"NV8\\\"],[[10063,10066],\\\"valid\\\",[],\\\"NV8\\\"],[[10067,10069],\\\"valid\\\",[],\\\"NV8\\\"],[[10070,10070],\\\"valid\\\",[],\\\"NV8\\\"],[[10071,10071],\\\"valid\\\",[],\\\"NV8\\\"],[[10072,10078],\\\"valid\\\",[],\\\"NV8\\\"],[[10079,10080],\\\"valid\\\",[],\\\"NV8\\\"],[[10081,10087],\\\"valid\\\",[],\\\"NV8\\\"],[[10088,10101],\\\"valid\\\",[],\\\"NV8\\\"],[[10102,10132],\\\"valid\\\",[],\\\"NV8\\\"],[[10133,10135],\\\"valid\\\",[],\\\"NV8\\\"],[[10136,10159],\\\"valid\\\",[],\\\"NV8\\\"],[[10160,10160],\\\"valid\\\",[],\\\"NV8\\\"],[[10161,10174],\\\"valid\\\",[],\\\"NV8\\\"],[[10175,10175],\\\"valid\\\",[],\\\"NV8\\\"],[[10176,10182],\\\"valid\\\",[],\\\"NV8\\\"],[[10183,10186],\\\"valid\\\",[],\\\"NV8\\\"],[[10187,10187],\\\"valid\\\",[],\\\"NV8\\\"],[[10188,10188],\\\"valid\\\",[],\\\"NV8\\\"],[[10189,10189],\\\"valid\\\",[],\\\"NV8\\\"],[[10190,10191],\\\"valid\\\",[],\\\"NV8\\\"],[[10192,10219],\\\"valid\\\",[],\\\"NV8\\\"],[[10220,10223],\\\"valid\\\",[],\\\"NV8\\\"],[[10224,10239],\\\"valid\\\",[],\\\"NV8\\\"],[[10240,10495],\\\"valid\\\",[],\\\"NV8\\\"],[[10496,10763],\\\"valid\\\",[],\\\"NV8\\\"],[[10764,10764],\\\"mapped\\\",[8747,8747,8747,8747]],[[10765,10867],\\\"valid\\\",[],\\\"NV8\\\"],[[10868,10868],\\\"disallowed_STD3_mapped\\\",[58,58,61]],[[10869,10869],\\\"disallowed_STD3_mapped\\\",[61,61]],[[10870,10870],\\\"disallowed_STD3_mapped\\\",[61,61,61]],[[10871,10971],\\\"valid\\\",[],\\\"NV8\\\"],[[10972,10972],\\\"mapped\\\",[10973,824]],[[10973,11007],\\\"valid\\\",[],\\\"NV8\\\"],[[11008,11021],\\\"valid\\\",[],\\\"NV8\\\"],[[11022,11027],\\\"valid\\\",[],\\\"NV8\\\"],[[11028,11034],\\\"valid\\\",[],\\\"NV8\\\"],[[11035,11039],\\\"valid\\\",[],\\\"NV8\\\"],[[11040,11043],\\\"valid\\\",[],\\\"NV8\\\"],[[11044,11084],\\\"valid\\\",[],\\\"NV8\\\"],[[11085,11087],\\\"valid\\\",[],\\\"NV8\\\"],[[11088,11092],\\\"valid\\\",[],\\\"NV8\\\"],[[11093,11097],\\\"valid\\\",[],\\\"NV8\\\"],[[11098,11123],\\\"valid\\\",[],\\\"NV8\\\"],[[11124,11125],\\\"disallowed\\\"],[[11126,11157],\\\"valid\\\",[],\\\"NV8\\\"],[[11158,11159],\\\"disallowed\\\"],[[11160,11193],\\\"valid\\\",[],\\\"NV8\\\"],[[11194,11196],\\\"disallowed\\\"],[[11197,11208],\\\"valid\\\",[],\\\"NV8\\\"],[[11209,11209],\\\"disallowed\\\"],[[11210,11217],\\\"valid\\\",[],\\\"NV8\\\"],[[11218,11243],\\\"disallowed\\\"],[[11244,11247],\\\"valid\\\",[],\\\"NV8\\\"],[[11248,11263],\\\"disallowed\\\"],[[11264,11264],\\\"mapped\\\",[11312]],[[11265,11265],\\\"mapped\\\",[11313]],[[11266,11266],\\\"mapped\\\",[11314]],[[11267,11267],\\\"mapped\\\",[11315]],[[11268,11268],\\\"mapped\\\",[11316]],[[11269,11269],\\\"mapped\\\",[11317]],[[11270,11270],\\\"mapped\\\",[11318]],[[11271,11271],\\\"mapped\\\",[11319]],[[11272,11272],\\\"mapped\\\",[11320]],[[11273,11273],\\\"mapped\\\",[11321]],[[11274,11274],\\\"mapped\\\",[11322]],[[11275,11275],\\\"mapped\\\",[11323]],[[11276,11276],\\\"mapped\\\",[11324]],[[11277,11277],\\\"mapped\\\",[11325]],[[11278,11278],\\\"mapped\\\",[11326]],[[11279,11279],\\\"mapped\\\",[11327]],[[11280,11280],\\\"mapped\\\",[11328]],[[11281,11281],\\\"mapped\\\",[11329]],[[11282,11282],\\\"mapped\\\",[11330]],[[11283,11283],\\\"mapped\\\",[11331]],[[11284,11284],\\\"mapped\\\",[11332]],[[11285,11285],\\\"mapped\\\",[11333]],[[11286,11286],\\\"mapped\\\",[11334]],[[11287,11287],\\\"mapped\\\",[11335]],[[11288,11288],\\\"mapped\\\",[11336]],[[11289,11289],\\\"mapped\\\",[11337]],[[11290,11290],\\\"mapped\\\",[11338]],[[11291,11291],\\\"mapped\\\",[11339]],[[11292,11292],\\\"mapped\\\",[11340]],[[11293,11293],\\\"mapped\\\",[11341]],[[11294,11294],\\\"mapped\\\",[11342]],[[11295,11295],\\\"mapped\\\",[11343]],[[11296,11296],\\\"mapped\\\",[11344]],[[11297,11297],\\\"mapped\\\",[11345]],[[11298,11298],\\\"mapped\\\",[11346]],[[11299,11299],\\\"mapped\\\",[11347]],[[11300,11300],\\\"mapped\\\",[11348]],[[11301,11301],\\\"mapped\\\",[11349]],[[11302,11302],\\\"mapped\\\",[11350]],[[11303,11303],\\\"mapped\\\",[11351]],[[11304,11304],\\\"mapped\\\",[11352]],[[11305,11305],\\\"mapped\\\",[11353]],[[11306,11306],\\\"mapped\\\",[11354]],[[11307,11307],\\\"mapped\\\",[11355]],[[11308,11308],\\\"mapped\\\",[11356]],[[11309,11309],\\\"mapped\\\",[11357]],[[11310,11310],\\\"mapped\\\",[11358]],[[11311,11311],\\\"disallowed\\\"],[[11312,11358],\\\"valid\\\"],[[11359,11359],\\\"disallowed\\\"],[[11360,11360],\\\"mapped\\\",[11361]],[[11361,11361],\\\"valid\\\"],[[11362,11362],\\\"mapped\\\",[619]],[[11363,11363],\\\"mapped\\\",[7549]],[[11364,11364],\\\"mapped\\\",[637]],[[11365,11366],\\\"valid\\\"],[[11367,11367],\\\"mapped\\\",[11368]],[[11368,11368],\\\"valid\\\"],[[11369,11369],\\\"mapped\\\",[11370]],[[11370,11370],\\\"valid\\\"],[[11371,11371],\\\"mapped\\\",[11372]],[[11372,11372],\\\"valid\\\"],[[11373,11373],\\\"mapped\\\",[593]],[[11374,11374],\\\"mapped\\\",[625]],[[11375,11375],\\\"mapped\\\",[592]],[[11376,11376],\\\"mapped\\\",[594]],[[11377,11377],\\\"valid\\\"],[[11378,11378],\\\"mapped\\\",[11379]],[[11379,11379],\\\"valid\\\"],[[11380,11380],\\\"valid\\\"],[[11381,11381],\\\"mapped\\\",[11382]],[[11382,11383],\\\"valid\\\"],[[11384,11387],\\\"valid\\\"],[[11388,11388],\\\"mapped\\\",[106]],[[11389,11389],\\\"mapped\\\",[118]],[[11390,11390],\\\"mapped\\\",[575]],[[11391,11391],\\\"mapped\\\",[576]],[[11392,11392],\\\"mapped\\\",[11393]],[[11393,11393],\\\"valid\\\"],[[11394,11394],\\\"mapped\\\",[11395]],[[11395,11395],\\\"valid\\\"],[[11396,11396],\\\"mapped\\\",[11397]],[[11397,11397],\\\"valid\\\"],[[11398,11398],\\\"mapped\\\",[11399]],[[11399,11399],\\\"valid\\\"],[[11400,11400],\\\"mapped\\\",[11401]],[[11401,11401],\\\"valid\\\"],[[11402,11402],\\\"mapped\\\",[11403]],[[11403,11403],\\\"valid\\\"],[[11404,11404],\\\"mapped\\\",[11405]],[[11405,11405],\\\"valid\\\"],[[11406,11406],\\\"mapped\\\",[11407]],[[11407,11407],\\\"valid\\\"],[[11408,11408],\\\"mapped\\\",[11409]],[[11409,11409],\\\"valid\\\"],[[11410,11410],\\\"mapped\\\",[11411]],[[11411,11411],\\\"valid\\\"],[[11412,11412],\\\"mapped\\\",[11413]],[[11413,11413],\\\"valid\\\"],[[11414,11414],\\\"mapped\\\",[11415]],[[11415,11415],\\\"valid\\\"],[[11416,11416],\\\"mapped\\\",[11417]],[[11417,11417],\\\"valid\\\"],[[11418,11418],\\\"mapped\\\",[11419]],[[11419,11419],\\\"valid\\\"],[[11420,11420],\\\"mapped\\\",[11421]],[[11421,11421],\\\"valid\\\"],[[11422,11422],\\\"mapped\\\",[11423]],[[11423,11423],\\\"valid\\\"],[[11424,11424],\\\"mapped\\\",[11425]],[[11425,11425],\\\"valid\\\"],[[11426,11426],\\\"mapped\\\",[11427]],[[11427,11427],\\\"valid\\\"],[[11428,11428],\\\"mapped\\\",[11429]],[[11429,11429],\\\"valid\\\"],[[11430,11430],\\\"mapped\\\",[11431]],[[11431,11431],\\\"valid\\\"],[[11432,11432],\\\"mapped\\\",[11433]],[[11433,11433],\\\"valid\\\"],[[11434,11434],\\\"mapped\\\",[11435]],[[11435,11435],\\\"valid\\\"],[[11436,11436],\\\"mapped\\\",[11437]],[[11437,11437],\\\"valid\\\"],[[11438,11438],\\\"mapped\\\",[11439]],[[11439,11439],\\\"valid\\\"],[[11440,11440],\\\"mapped\\\",[11441]],[[11441,11441],\\\"valid\\\"],[[11442,11442],\\\"mapped\\\",[11443]],[[11443,11443],\\\"valid\\\"],[[11444,11444],\\\"mapped\\\",[11445]],[[11445,11445],\\\"valid\\\"],[[11446,11446],\\\"mapped\\\",[11447]],[[11447,11447],\\\"valid\\\"],[[11448,11448],\\\"mapped\\\",[11449]],[[11449,11449],\\\"valid\\\"],[[11450,11450],\\\"mapped\\\",[11451]],[[11451,11451],\\\"valid\\\"],[[11452,11452],\\\"mapped\\\",[11453]],[[11453,11453],\\\"valid\\\"],[[11454,11454],\\\"mapped\\\",[11455]],[[11455,11455],\\\"valid\\\"],[[11456,11456],\\\"mapped\\\",[11457]],[[11457,11457],\\\"valid\\\"],[[11458,11458],\\\"mapped\\\",[11459]],[[11459,11459],\\\"valid\\\"],[[11460,11460],\\\"mapped\\\",[11461]],[[11461,11461],\\\"valid\\\"],[[11462,11462],\\\"mapped\\\",[11463]],[[11463,11463],\\\"valid\\\"],[[11464,11464],\\\"mapped\\\",[11465]],[[11465,11465],\\\"valid\\\"],[[11466,11466],\\\"mapped\\\",[11467]],[[11467,11467],\\\"valid\\\"],[[11468,11468],\\\"mapped\\\",[11469]],[[11469,11469],\\\"valid\\\"],[[11470,11470],\\\"mapped\\\",[11471]],[[11471,11471],\\\"valid\\\"],[[11472,11472],\\\"mapped\\\",[11473]],[[11473,11473],\\\"valid\\\"],[[11474,11474],\\\"mapped\\\",[11475]],[[11475,11475],\\\"valid\\\"],[[11476,11476],\\\"mapped\\\",[11477]],[[11477,11477],\\\"valid\\\"],[[11478,11478],\\\"mapped\\\",[11479]],[[11479,11479],\\\"valid\\\"],[[11480,11480],\\\"mapped\\\",[11481]],[[11481,11481],\\\"valid\\\"],[[11482,11482],\\\"mapped\\\",[11483]],[[11483,11483],\\\"valid\\\"],[[11484,11484],\\\"mapped\\\",[11485]],[[11485,11485],\\\"valid\\\"],[[11486,11486],\\\"mapped\\\",[11487]],[[11487,11487],\\\"valid\\\"],[[11488,11488],\\\"mapped\\\",[11489]],[[11489,11489],\\\"valid\\\"],[[11490,11490],\\\"mapped\\\",[11491]],[[11491,11492],\\\"valid\\\"],[[11493,11498],\\\"valid\\\",[],\\\"NV8\\\"],[[11499,11499],\\\"mapped\\\",[11500]],[[11500,11500],\\\"valid\\\"],[[11501,11501],\\\"mapped\\\",[11502]],[[11502,11505],\\\"valid\\\"],[[11506,11506],\\\"mapped\\\",[11507]],[[11507,11507],\\\"valid\\\"],[[11508,11512],\\\"disallowed\\\"],[[11513,11519],\\\"valid\\\",[],\\\"NV8\\\"],[[11520,11557],\\\"valid\\\"],[[11558,11558],\\\"disallowed\\\"],[[11559,11559],\\\"valid\\\"],[[11560,11564],\\\"disallowed\\\"],[[11565,11565],\\\"valid\\\"],[[11566,11567],\\\"disallowed\\\"],[[11568,11621],\\\"valid\\\"],[[11622,11623],\\\"valid\\\"],[[11624,11630],\\\"disallowed\\\"],[[11631,11631],\\\"mapped\\\",[11617]],[[11632,11632],\\\"valid\\\",[],\\\"NV8\\\"],[[11633,11646],\\\"disallowed\\\"],[[11647,11647],\\\"valid\\\"],[[11648,11670],\\\"valid\\\"],[[11671,11679],\\\"disallowed\\\"],[[11680,11686],\\\"valid\\\"],[[11687,11687],\\\"disallowed\\\"],[[11688,11694],\\\"valid\\\"],[[11695,11695],\\\"disallowed\\\"],[[11696,11702],\\\"valid\\\"],[[11703,11703],\\\"disallowed\\\"],[[11704,11710],\\\"valid\\\"],[[11711,11711],\\\"disallowed\\\"],[[11712,11718],\\\"valid\\\"],[[11719,11719],\\\"disallowed\\\"],[[11720,11726],\\\"valid\\\"],[[11727,11727],\\\"disallowed\\\"],[[11728,11734],\\\"valid\\\"],[[11735,11735],\\\"disallowed\\\"],[[11736,11742],\\\"valid\\\"],[[11743,11743],\\\"disallowed\\\"],[[11744,11775],\\\"valid\\\"],[[11776,11799],\\\"valid\\\",[],\\\"NV8\\\"],[[11800,11803],\\\"valid\\\",[],\\\"NV8\\\"],[[11804,11805],\\\"valid\\\",[],\\\"NV8\\\"],[[11806,11822],\\\"valid\\\",[],\\\"NV8\\\"],[[11823,11823],\\\"valid\\\"],[[11824,11824],\\\"valid\\\",[],\\\"NV8\\\"],[[11825,11825],\\\"valid\\\",[],\\\"NV8\\\"],[[11826,11835],\\\"valid\\\",[],\\\"NV8\\\"],[[11836,11842],\\\"valid\\\",[],\\\"NV8\\\"],[[11843,11903],\\\"disallowed\\\"],[[11904,11929],\\\"valid\\\",[],\\\"NV8\\\"],[[11930,11930],\\\"disallowed\\\"],[[11931,11934],\\\"valid\\\",[],\\\"NV8\\\"],[[11935,11935],\\\"mapped\\\",[27597]],[[11936,12018],\\\"valid\\\",[],\\\"NV8\\\"],[[12019,12019],\\\"mapped\\\",[40863]],[[12020,12031],\\\"disallowed\\\"],[[12032,12032],\\\"mapped\\\",[19968]],[[12033,12033],\\\"mapped\\\",[20008]],[[12034,12034],\\\"mapped\\\",[20022]],[[12035,12035],\\\"mapped\\\",[20031]],[[12036,12036],\\\"mapped\\\",[20057]],[[12037,12037],\\\"mapped\\\",[20101]],[[12038,12038],\\\"mapped\\\",[20108]],[[12039,12039],\\\"mapped\\\",[20128]],[[12040,12040],\\\"mapped\\\",[20154]],[[12041,12041],\\\"mapped\\\",[20799]],[[12042,12042],\\\"mapped\\\",[20837]],[[12043,12043],\\\"mapped\\\",[20843]],[[12044,12044],\\\"mapped\\\",[20866]],[[12045,12045],\\\"mapped\\\",[20886]],[[12046,12046],\\\"mapped\\\",[20907]],[[12047,12047],\\\"mapped\\\",[20960]],[[12048,12048],\\\"mapped\\\",[20981]],[[12049,12049],\\\"mapped\\\",[20992]],[[12050,12050],\\\"mapped\\\",[21147]],[[12051,12051],\\\"mapped\\\",[21241]],[[12052,12052],\\\"mapped\\\",[21269]],[[12053,12053],\\\"mapped\\\",[21274]],[[12054,12054],\\\"mapped\\\",[21304]],[[12055,12055],\\\"mapped\\\",[21313]],[[12056,12056],\\\"mapped\\\",[21340]],[[12057,12057],\\\"mapped\\\",[21353]],[[12058,12058],\\\"mapped\\\",[21378]],[[12059,12059],\\\"mapped\\\",[21430]],[[12060,12060],\\\"mapped\\\",[21448]],[[12061,12061],\\\"mapped\\\",[21475]],[[12062,12062],\\\"mapped\\\",[22231]],[[12063,12063],\\\"mapped\\\",[22303]],[[12064,12064],\\\"mapped\\\",[22763]],[[12065,12065],\\\"mapped\\\",[22786]],[[12066,12066],\\\"mapped\\\",[22794]],[[12067,12067],\\\"mapped\\\",[22805]],[[12068,12068],\\\"mapped\\\",[22823]],[[12069,12069],\\\"mapped\\\",[22899]],[[12070,12070],\\\"mapped\\\",[23376]],[[12071,12071],\\\"mapped\\\",[23424]],[[12072,12072],\\\"mapped\\\",[23544]],[[12073,12073],\\\"mapped\\\",[23567]],[[12074,12074],\\\"mapped\\\",[23586]],[[12075,12075],\\\"mapped\\\",[23608]],[[12076,12076],\\\"mapped\\\",[23662]],[[12077,12077],\\\"mapped\\\",[23665]],[[12078,12078],\\\"mapped\\\",[24027]],[[12079,12079],\\\"mapped\\\",[24037]],[[12080,12080],\\\"mapped\\\",[24049]],[[12081,12081],\\\"mapped\\\",[24062]],[[12082,12082],\\\"mapped\\\",[24178]],[[12083,12083],\\\"mapped\\\",[24186]],[[12084,12084],\\\"mapped\\\",[24191]],[[12085,12085],\\\"mapped\\\",[24308]],[[12086,12086],\\\"mapped\\\",[24318]],[[12087,12087],\\\"mapped\\\",[24331]],[[12088,12088],\\\"mapped\\\",[24339]],[[12089,12089],\\\"mapped\\\",[24400]],[[12090,12090],\\\"mapped\\\",[24417]],[[12091,12091],\\\"mapped\\\",[24435]],[[12092,12092],\\\"mapped\\\",[24515]],[[12093,12093],\\\"mapped\\\",[25096]],[[12094,12094],\\\"mapped\\\",[25142]],[[12095,12095],\\\"mapped\\\",[25163]],[[12096,12096],\\\"mapped\\\",[25903]],[[12097,12097],\\\"mapped\\\",[25908]],[[12098,12098],\\\"mapped\\\",[25991]],[[12099,12099],\\\"mapped\\\",[26007]],[[12100,12100],\\\"mapped\\\",[26020]],[[12101,12101],\\\"mapped\\\",[26041]],[[12102,12102],\\\"mapped\\\",[26080]],[[12103,12103],\\\"mapped\\\",[26085]],[[12104,12104],\\\"mapped\\\",[26352]],[[12105,12105],\\\"mapped\\\",[26376]],[[12106,12106],\\\"mapped\\\",[26408]],[[12107,12107],\\\"mapped\\\",[27424]],[[12108,12108],\\\"mapped\\\",[27490]],[[12109,12109],\\\"mapped\\\",[27513]],[[12110,12110],\\\"mapped\\\",[27571]],[[12111,12111],\\\"mapped\\\",[27595]],[[12112,12112],\\\"mapped\\\",[27604]],[[12113,12113],\\\"mapped\\\",[27611]],[[12114,12114],\\\"mapped\\\",[27663]],[[12115,12115],\\\"mapped\\\",[27668]],[[12116,12116],\\\"mapped\\\",[27700]],[[12117,12117],\\\"mapped\\\",[28779]],[[12118,12118],\\\"mapped\\\",[29226]],[[12119,12119],\\\"mapped\\\",[29238]],[[12120,12120],\\\"mapped\\\",[29243]],[[12121,12121],\\\"mapped\\\",[29247]],[[12122,12122],\\\"mapped\\\",[29255]],[[12123,12123],\\\"mapped\\\",[29273]],[[12124,12124],\\\"mapped\\\",[29275]],[[12125,12125],\\\"mapped\\\",[29356]],[[12126,12126],\\\"mapped\\\",[29572]],[[12127,12127],\\\"mapped\\\",[29577]],[[12128,12128],\\\"mapped\\\",[29916]],[[12129,12129],\\\"mapped\\\",[29926]],[[12130,12130],\\\"mapped\\\",[29976]],[[12131,12131],\\\"mapped\\\",[29983]],[[12132,12132],\\\"mapped\\\",[29992]],[[12133,12133],\\\"mapped\\\",[30000]],[[12134,12134],\\\"mapped\\\",[30091]],[[12135,12135],\\\"mapped\\\",[30098]],[[12136,12136],\\\"mapped\\\",[30326]],[[12137,12137],\\\"mapped\\\",[30333]],[[12138,12138],\\\"mapped\\\",[30382]],[[12139,12139],\\\"mapped\\\",[30399]],[[12140,12140],\\\"mapped\\\",[30446]],[[12141,12141],\\\"mapped\\\",[30683]],[[12142,12142],\\\"mapped\\\",[30690]],[[12143,12143],\\\"mapped\\\",[30707]],[[12144,12144],\\\"mapped\\\",[31034]],[[12145,12145],\\\"mapped\\\",[31160]],[[12146,12146],\\\"mapped\\\",[31166]],[[12147,12147],\\\"mapped\\\",[31348]],[[12148,12148],\\\"mapped\\\",[31435]],[[12149,12149],\\\"mapped\\\",[31481]],[[12150,12150],\\\"mapped\\\",[31859]],[[12151,12151],\\\"mapped\\\",[31992]],[[12152,12152],\\\"mapped\\\",[32566]],[[12153,12153],\\\"mapped\\\",[32593]],[[12154,12154],\\\"mapped\\\",[32650]],[[12155,12155],\\\"mapped\\\",[32701]],[[12156,12156],\\\"mapped\\\",[32769]],[[12157,12157],\\\"mapped\\\",[32780]],[[12158,12158],\\\"mapped\\\",[32786]],[[12159,12159],\\\"mapped\\\",[32819]],[[12160,12160],\\\"mapped\\\",[32895]],[[12161,12161],\\\"mapped\\\",[32905]],[[12162,12162],\\\"mapped\\\",[33251]],[[12163,12163],\\\"mapped\\\",[33258]],[[12164,12164],\\\"mapped\\\",[33267]],[[12165,12165],\\\"mapped\\\",[33276]],[[12166,12166],\\\"mapped\\\",[33292]],[[12167,12167],\\\"mapped\\\",[33307]],[[12168,12168],\\\"mapped\\\",[33311]],[[12169,12169],\\\"mapped\\\",[33390]],[[12170,12170],\\\"mapped\\\",[33394]],[[12171,12171],\\\"mapped\\\",[33400]],[[12172,12172],\\\"mapped\\\",[34381]],[[12173,12173],\\\"mapped\\\",[34411]],[[12174,12174],\\\"mapped\\\",[34880]],[[12175,12175],\\\"mapped\\\",[34892]],[[12176,12176],\\\"mapped\\\",[34915]],[[12177,12177],\\\"mapped\\\",[35198]],[[12178,12178],\\\"mapped\\\",[35211]],[[12179,12179],\\\"mapped\\\",[35282]],[[12180,12180],\\\"mapped\\\",[35328]],[[12181,12181],\\\"mapped\\\",[35895]],[[12182,12182],\\\"mapped\\\",[35910]],[[12183,12183],\\\"mapped\\\",[35925]],[[12184,12184],\\\"mapped\\\",[35960]],[[12185,12185],\\\"mapped\\\",[35997]],[[12186,12186],\\\"mapped\\\",[36196]],[[12187,12187],\\\"mapped\\\",[36208]],[[12188,12188],\\\"mapped\\\",[36275]],[[12189,12189],\\\"mapped\\\",[36523]],[[12190,12190],\\\"mapped\\\",[36554]],[[12191,12191],\\\"mapped\\\",[36763]],[[12192,12192],\\\"mapped\\\",[36784]],[[12193,12193],\\\"mapped\\\",[36789]],[[12194,12194],\\\"mapped\\\",[37009]],[[12195,12195],\\\"mapped\\\",[37193]],[[12196,12196],\\\"mapped\\\",[37318]],[[12197,12197],\\\"mapped\\\",[37324]],[[12198,12198],\\\"mapped\\\",[37329]],[[12199,12199],\\\"mapped\\\",[38263]],[[12200,12200],\\\"mapped\\\",[38272]],[[12201,12201],\\\"mapped\\\",[38428]],[[12202,12202],\\\"mapped\\\",[38582]],[[12203,12203],\\\"mapped\\\",[38585]],[[12204,12204],\\\"mapped\\\",[38632]],[[12205,12205],\\\"mapped\\\",[38737]],[[12206,12206],\\\"mapped\\\",[38750]],[[12207,12207],\\\"mapped\\\",[38754]],[[12208,12208],\\\"mapped\\\",[38761]],[[12209,12209],\\\"mapped\\\",[38859]],[[12210,12210],\\\"mapped\\\",[38893]],[[12211,12211],\\\"mapped\\\",[38899]],[[12212,12212],\\\"mapped\\\",[38913]],[[12213,12213],\\\"mapped\\\",[39080]],[[12214,12214],\\\"mapped\\\",[39131]],[[12215,12215],\\\"mapped\\\",[39135]],[[12216,12216],\\\"mapped\\\",[39318]],[[12217,12217],\\\"mapped\\\",[39321]],[[12218,12218],\\\"mapped\\\",[39340]],[[12219,12219],\\\"mapped\\\",[39592]],[[12220,12220],\\\"mapped\\\",[39640]],[[12221,12221],\\\"mapped\\\",[39647]],[[12222,12222],\\\"mapped\\\",[39717]],[[12223,12223],\\\"mapped\\\",[39727]],[[12224,12224],\\\"mapped\\\",[39730]],[[12225,12225],\\\"mapped\\\",[39740]],[[12226,12226],\\\"mapped\\\",[39770]],[[12227,12227],\\\"mapped\\\",[40165]],[[12228,12228],\\\"mapped\\\",[40565]],[[12229,12229],\\\"mapped\\\",[40575]],[[12230,12230],\\\"mapped\\\",[40613]],[[12231,12231],\\\"mapped\\\",[40635]],[[12232,12232],\\\"mapped\\\",[40643]],[[12233,12233],\\\"mapped\\\",[40653]],[[12234,12234],\\\"mapped\\\",[40657]],[[12235,12235],\\\"mapped\\\",[40697]],[[12236,12236],\\\"mapped\\\",[40701]],[[12237,12237],\\\"mapped\\\",[40718]],[[12238,12238],\\\"mapped\\\",[40723]],[[12239,12239],\\\"mapped\\\",[40736]],[[12240,12240],\\\"mapped\\\",[40763]],[[12241,12241],\\\"mapped\\\",[40778]],[[12242,12242],\\\"mapped\\\",[40786]],[[12243,12243],\\\"mapped\\\",[40845]],[[12244,12244],\\\"mapped\\\",[40860]],[[12245,12245],\\\"mapped\\\",[40864]],[[12246,12271],\\\"disallowed\\\"],[[12272,12283],\\\"disallowed\\\"],[[12284,12287],\\\"disallowed\\\"],[[12288,12288],\\\"disallowed_STD3_mapped\\\",[32]],[[12289,12289],\\\"valid\\\",[],\\\"NV8\\\"],[[12290,12290],\\\"mapped\\\",[46]],[[12291,12292],\\\"valid\\\",[],\\\"NV8\\\"],[[12293,12295],\\\"valid\\\"],[[12296,12329],\\\"valid\\\",[],\\\"NV8\\\"],[[12330,12333],\\\"valid\\\"],[[12334,12341],\\\"valid\\\",[],\\\"NV8\\\"],[[12342,12342],\\\"mapped\\\",[12306]],[[12343,12343],\\\"valid\\\",[],\\\"NV8\\\"],[[12344,12344],\\\"mapped\\\",[21313]],[[12345,12345],\\\"mapped\\\",[21316]],[[12346,12346],\\\"mapped\\\",[21317]],[[12347,12347],\\\"valid\\\",[],\\\"NV8\\\"],[[12348,12348],\\\"valid\\\"],[[12349,12349],\\\"valid\\\",[],\\\"NV8\\\"],[[12350,12350],\\\"valid\\\",[],\\\"NV8\\\"],[[12351,12351],\\\"valid\\\",[],\\\"NV8\\\"],[[12352,12352],\\\"disallowed\\\"],[[12353,12436],\\\"valid\\\"],[[12437,12438],\\\"valid\\\"],[[12439,12440],\\\"disallowed\\\"],[[12441,12442],\\\"valid\\\"],[[12443,12443],\\\"disallowed_STD3_mapped\\\",[32,12441]],[[12444,12444],\\\"disallowed_STD3_mapped\\\",[32,12442]],[[12445,12446],\\\"valid\\\"],[[12447,12447],\\\"mapped\\\",[12424,12426]],[[12448,12448],\\\"valid\\\",[],\\\"NV8\\\"],[[12449,12542],\\\"valid\\\"],[[12543,12543],\\\"mapped\\\",[12467,12488]],[[12544,12548],\\\"disallowed\\\"],[[12549,12588],\\\"valid\\\"],[[12589,12589],\\\"valid\\\"],[[12590,12592],\\\"disallowed\\\"],[[12593,12593],\\\"mapped\\\",[4352]],[[12594,12594],\\\"mapped\\\",[4353]],[[12595,12595],\\\"mapped\\\",[4522]],[[12596,12596],\\\"mapped\\\",[4354]],[[12597,12597],\\\"mapped\\\",[4524]],[[12598,12598],\\\"mapped\\\",[4525]],[[12599,12599],\\\"mapped\\\",[4355]],[[12600,12600],\\\"mapped\\\",[4356]],[[12601,12601],\\\"mapped\\\",[4357]],[[12602,12602],\\\"mapped\\\",[4528]],[[12603,12603],\\\"mapped\\\",[4529]],[[12604,12604],\\\"mapped\\\",[4530]],[[12605,12605],\\\"mapped\\\",[4531]],[[12606,12606],\\\"mapped\\\",[4532]],[[12607,12607],\\\"mapped\\\",[4533]],[[12608,12608],\\\"mapped\\\",[4378]],[[12609,12609],\\\"mapped\\\",[4358]],[[12610,12610],\\\"mapped\\\",[4359]],[[12611,12611],\\\"mapped\\\",[4360]],[[12612,12612],\\\"mapped\\\",[4385]],[[12613,12613],\\\"mapped\\\",[4361]],[[12614,12614],\\\"mapped\\\",[4362]],[[12615,12615],\\\"mapped\\\",[4363]],[[12616,12616],\\\"mapped\\\",[4364]],[[12617,12617],\\\"mapped\\\",[4365]],[[12618,12618],\\\"mapped\\\",[4366]],[[12619,12619],\\\"mapped\\\",[4367]],[[12620,12620],\\\"mapped\\\",[4368]],[[12621,12621],\\\"mapped\\\",[4369]],[[12622,12622],\\\"mapped\\\",[4370]],[[12623,12623],\\\"mapped\\\",[4449]],[[12624,12624],\\\"mapped\\\",[4450]],[[12625,12625],\\\"mapped\\\",[4451]],[[12626,12626],\\\"mapped\\\",[4452]],[[12627,12627],\\\"mapped\\\",[4453]],[[12628,12628],\\\"mapped\\\",[4454]],[[12629,12629],\\\"mapped\\\",[4455]],[[12630,12630],\\\"mapped\\\",[4456]],[[12631,12631],\\\"mapped\\\",[4457]],[[12632,12632],\\\"mapped\\\",[4458]],[[12633,12633],\\\"mapped\\\",[4459]],[[12634,12634],\\\"mapped\\\",[4460]],[[12635,12635],\\\"mapped\\\",[4461]],[[12636,12636],\\\"mapped\\\",[4462]],[[12637,12637],\\\"mapped\\\",[4463]],[[12638,12638],\\\"mapped\\\",[4464]],[[12639,12639],\\\"mapped\\\",[4465]],[[12640,12640],\\\"mapped\\\",[4466]],[[12641,12641],\\\"mapped\\\",[4467]],[[12642,12642],\\\"mapped\\\",[4468]],[[12643,12643],\\\"mapped\\\",[4469]],[[12644,12644],\\\"disallowed\\\"],[[12645,12645],\\\"mapped\\\",[4372]],[[12646,12646],\\\"mapped\\\",[4373]],[[12647,12647],\\\"mapped\\\",[4551]],[[12648,12648],\\\"mapped\\\",[4552]],[[12649,12649],\\\"mapped\\\",[4556]],[[12650,12650],\\\"mapped\\\",[4558]],[[12651,12651],\\\"mapped\\\",[4563]],[[12652,12652],\\\"mapped\\\",[4567]],[[12653,12653],\\\"mapped\\\",[4569]],[[12654,12654],\\\"mapped\\\",[4380]],[[12655,12655],\\\"mapped\\\",[4573]],[[12656,12656],\\\"mapped\\\",[4575]],[[12657,12657],\\\"mapped\\\",[4381]],[[12658,12658],\\\"mapped\\\",[4382]],[[12659,12659],\\\"mapped\\\",[4384]],[[12660,12660],\\\"mapped\\\",[4386]],[[12661,12661],\\\"mapped\\\",[4387]],[[12662,12662],\\\"mapped\\\",[4391]],[[12663,12663],\\\"mapped\\\",[4393]],[[12664,12664],\\\"mapped\\\",[4395]],[[12665,12665],\\\"mapped\\\",[4396]],[[12666,12666],\\\"mapped\\\",[4397]],[[12667,12667],\\\"mapped\\\",[4398]],[[12668,12668],\\\"mapped\\\",[4399]],[[12669,12669],\\\"mapped\\\",[4402]],[[12670,12670],\\\"mapped\\\",[4406]],[[12671,12671],\\\"mapped\\\",[4416]],[[12672,12672],\\\"mapped\\\",[4423]],[[12673,12673],\\\"mapped\\\",[4428]],[[12674,12674],\\\"mapped\\\",[4593]],[[12675,12675],\\\"mapped\\\",[4594]],[[12676,12676],\\\"mapped\\\",[4439]],[[12677,12677],\\\"mapped\\\",[4440]],[[12678,12678],\\\"mapped\\\",[4441]],[[12679,12679],\\\"mapped\\\",[4484]],[[12680,12680],\\\"mapped\\\",[4485]],[[12681,12681],\\\"mapped\\\",[4488]],[[12682,12682],\\\"mapped\\\",[4497]],[[12683,12683],\\\"mapped\\\",[4498]],[[12684,12684],\\\"mapped\\\",[4500]],[[12685,12685],\\\"mapped\\\",[4510]],[[12686,12686],\\\"mapped\\\",[4513]],[[12687,12687],\\\"disallowed\\\"],[[12688,12689],\\\"valid\\\",[],\\\"NV8\\\"],[[12690,12690],\\\"mapped\\\",[19968]],[[12691,12691],\\\"mapped\\\",[20108]],[[12692,12692],\\\"mapped\\\",[19977]],[[12693,12693],\\\"mapped\\\",[22235]],[[12694,12694],\\\"mapped\\\",[19978]],[[12695,12695],\\\"mapped\\\",[20013]],[[12696,12696],\\\"mapped\\\",[19979]],[[12697,12697],\\\"mapped\\\",[30002]],[[12698,12698],\\\"mapped\\\",[20057]],[[12699,12699],\\\"mapped\\\",[19993]],[[12700,12700],\\\"mapped\\\",[19969]],[[12701,12701],\\\"mapped\\\",[22825]],[[12702,12702],\\\"mapped\\\",[22320]],[[12703,12703],\\\"mapped\\\",[20154]],[[12704,12727],\\\"valid\\\"],[[12728,12730],\\\"valid\\\"],[[12731,12735],\\\"disallowed\\\"],[[12736,12751],\\\"valid\\\",[],\\\"NV8\\\"],[[12752,12771],\\\"valid\\\",[],\\\"NV8\\\"],[[12772,12783],\\\"disallowed\\\"],[[12784,12799],\\\"valid\\\"],[[12800,12800],\\\"disallowed_STD3_mapped\\\",[40,4352,41]],[[12801,12801],\\\"disallowed_STD3_mapped\\\",[40,4354,41]],[[12802,12802],\\\"disallowed_STD3_mapped\\\",[40,4355,41]],[[12803,12803],\\\"disallowed_STD3_mapped\\\",[40,4357,41]],[[12804,12804],\\\"disallowed_STD3_mapped\\\",[40,4358,41]],[[12805,12805],\\\"disallowed_STD3_mapped\\\",[40,4359,41]],[[12806,12806],\\\"disallowed_STD3_mapped\\\",[40,4361,41]],[[12807,12807],\\\"disallowed_STD3_mapped\\\",[40,4363,41]],[[12808,12808],\\\"disallowed_STD3_mapped\\\",[40,4364,41]],[[12809,12809],\\\"disallowed_STD3_mapped\\\",[40,4366,41]],[[12810,12810],\\\"disallowed_STD3_mapped\\\",[40,4367,41]],[[12811,12811],\\\"disallowed_STD3_mapped\\\",[40,4368,41]],[[12812,12812],\\\"disallowed_STD3_mapped\\\",[40,4369,41]],[[12813,12813],\\\"disallowed_STD3_mapped\\\",[40,4370,41]],[[12814,12814],\\\"disallowed_STD3_mapped\\\",[40,44032,41]],[[12815,12815],\\\"disallowed_STD3_mapped\\\",[40,45208,41]],[[12816,12816],\\\"disallowed_STD3_mapped\\\",[40,45796,41]],[[12817,12817],\\\"disallowed_STD3_mapped\\\",[40,46972,41]],[[12818,12818],\\\"disallowed_STD3_mapped\\\",[40,47560,41]],[[12819,12819],\\\"disallowed_STD3_mapped\\\",[40,48148,41]],[[12820,12820],\\\"disallowed_STD3_mapped\\\",[40,49324,41]],[[12821,12821],\\\"disallowed_STD3_mapped\\\",[40,50500,41]],[[12822,12822],\\\"disallowed_STD3_mapped\\\",[40,51088,41]],[[12823,12823],\\\"disallowed_STD3_mapped\\\",[40,52264,41]],[[12824,12824],\\\"disallowed_STD3_mapped\\\",[40,52852,41]],[[12825,12825],\\\"disallowed_STD3_mapped\\\",[40,53440,41]],[[12826,12826],\\\"disallowed_STD3_mapped\\\",[40,54028,41]],[[12827,12827],\\\"disallowed_STD3_mapped\\\",[40,54616,41]],[[12828,12828],\\\"disallowed_STD3_mapped\\\",[40,51452,41]],[[12829,12829],\\\"disallowed_STD3_mapped\\\",[40,50724,51204,41]],[[12830,12830],\\\"disallowed_STD3_mapped\\\",[40,50724,54980,41]],[[12831,12831],\\\"disallowed\\\"],[[12832,12832],\\\"disallowed_STD3_mapped\\\",[40,19968,41]],[[12833,12833],\\\"disallowed_STD3_mapped\\\",[40,20108,41]],[[12834,12834],\\\"disallowed_STD3_mapped\\\",[40,19977,41]],[[12835,12835],\\\"disallowed_STD3_mapped\\\",[40,22235,41]],[[12836,12836],\\\"disallowed_STD3_mapped\\\",[40,20116,41]],[[12837,12837],\\\"disallowed_STD3_mapped\\\",[40,20845,41]],[[12838,12838],\\\"disallowed_STD3_mapped\\\",[40,19971,41]],[[12839,12839],\\\"disallowed_STD3_mapped\\\",[40,20843,41]],[[12840,12840],\\\"disallowed_STD3_mapped\\\",[40,20061,41]],[[12841,12841],\\\"disallowed_STD3_mapped\\\",[40,21313,41]],[[12842,12842],\\\"disallowed_STD3_mapped\\\",[40,26376,41]],[[12843,12843],\\\"disallowed_STD3_mapped\\\",[40,28779,41]],[[12844,12844],\\\"disallowed_STD3_mapped\\\",[40,27700,41]],[[12845,12845],\\\"disallowed_STD3_mapped\\\",[40,26408,41]],[[12846,12846],\\\"disallowed_STD3_mapped\\\",[40,37329,41]],[[12847,12847],\\\"disallowed_STD3_mapped\\\",[40,22303,41]],[[12848,12848],\\\"disallowed_STD3_mapped\\\",[40,26085,41]],[[12849,12849],\\\"disallowed_STD3_mapped\\\",[40,26666,41]],[[12850,12850],\\\"disallowed_STD3_mapped\\\",[40,26377,41]],[[12851,12851],\\\"disallowed_STD3_mapped\\\",[40,31038,41]],[[12852,12852],\\\"disallowed_STD3_mapped\\\",[40,21517,41]],[[12853,12853],\\\"disallowed_STD3_mapped\\\",[40,29305,41]],[[12854,12854],\\\"disallowed_STD3_mapped\\\",[40,36001,41]],[[12855,12855],\\\"disallowed_STD3_mapped\\\",[40,31069,41]],[[12856,12856],\\\"disallowed_STD3_mapped\\\",[40,21172,41]],[[12857,12857],\\\"disallowed_STD3_mapped\\\",[40,20195,41]],[[12858,12858],\\\"disallowed_STD3_mapped\\\",[40,21628,41]],[[12859,12859],\\\"disallowed_STD3_mapped\\\",[40,23398,41]],[[12860,12860],\\\"disallowed_STD3_mapped\\\",[40,30435,41]],[[12861,12861],\\\"disallowed_STD3_mapped\\\",[40,20225,41]],[[12862,12862],\\\"disallowed_STD3_mapped\\\",[40,36039,41]],[[12863,12863],\\\"disallowed_STD3_mapped\\\",[40,21332,41]],[[12864,12864],\\\"disallowed_STD3_mapped\\\",[40,31085,41]],[[12865,12865],\\\"disallowed_STD3_mapped\\\",[40,20241,41]],[[12866,12866],\\\"disallowed_STD3_mapped\\\",[40,33258,41]],[[12867,12867],\\\"disallowed_STD3_mapped\\\",[40,33267,41]],[[12868,12868],\\\"mapped\\\",[21839]],[[12869,12869],\\\"mapped\\\",[24188]],[[12870,12870],\\\"mapped\\\",[25991]],[[12871,12871],\\\"mapped\\\",[31631]],[[12872,12879],\\\"valid\\\",[],\\\"NV8\\\"],[[12880,12880],\\\"mapped\\\",[112,116,101]],[[12881,12881],\\\"mapped\\\",[50,49]],[[12882,12882],\\\"mapped\\\",[50,50]],[[12883,12883],\\\"mapped\\\",[50,51]],[[12884,12884],\\\"mapped\\\",[50,52]],[[12885,12885],\\\"mapped\\\",[50,53]],[[12886,12886],\\\"mapped\\\",[50,54]],[[12887,12887],\\\"mapped\\\",[50,55]],[[12888,12888],\\\"mapped\\\",[50,56]],[[12889,12889],\\\"mapped\\\",[50,57]],[[12890,12890],\\\"mapped\\\",[51,48]],[[12891,12891],\\\"mapped\\\",[51,49]],[[12892,12892],\\\"mapped\\\",[51,50]],[[12893,12893],\\\"mapped\\\",[51,51]],[[12894,12894],\\\"mapped\\\",[51,52]],[[12895,12895],\\\"mapped\\\",[51,53]],[[12896,12896],\\\"mapped\\\",[4352]],[[12897,12897],\\\"mapped\\\",[4354]],[[12898,12898],\\\"mapped\\\",[4355]],[[12899,12899],\\\"mapped\\\",[4357]],[[12900,12900],\\\"mapped\\\",[4358]],[[12901,12901],\\\"mapped\\\",[4359]],[[12902,12902],\\\"mapped\\\",[4361]],[[12903,12903],\\\"mapped\\\",[4363]],[[12904,12904],\\\"mapped\\\",[4364]],[[12905,12905],\\\"mapped\\\",[4366]],[[12906,12906],\\\"mapped\\\",[4367]],[[12907,12907],\\\"mapped\\\",[4368]],[[12908,12908],\\\"mapped\\\",[4369]],[[12909,12909],\\\"mapped\\\",[4370]],[[12910,12910],\\\"mapped\\\",[44032]],[[12911,12911],\\\"mapped\\\",[45208]],[[12912,12912],\\\"mapped\\\",[45796]],[[12913,12913],\\\"mapped\\\",[46972]],[[12914,12914],\\\"mapped\\\",[47560]],[[12915,12915],\\\"mapped\\\",[48148]],[[12916,12916],\\\"mapped\\\",[49324]],[[12917,12917],\\\"mapped\\\",[50500]],[[12918,12918],\\\"mapped\\\",[51088]],[[12919,12919],\\\"mapped\\\",[52264]],[[12920,12920],\\\"mapped\\\",[52852]],[[12921,12921],\\\"mapped\\\",[53440]],[[12922,12922],\\\"mapped\\\",[54028]],[[12923,12923],\\\"mapped\\\",[54616]],[[12924,12924],\\\"mapped\\\",[52280,44256]],[[12925,12925],\\\"mapped\\\",[51452,51032]],[[12926,12926],\\\"mapped\\\",[50864]],[[12927,12927],\\\"valid\\\",[],\\\"NV8\\\"],[[12928,12928],\\\"mapped\\\",[19968]],[[12929,12929],\\\"mapped\\\",[20108]],[[12930,12930],\\\"mapped\\\",[19977]],[[12931,12931],\\\"mapped\\\",[22235]],[[12932,12932],\\\"mapped\\\",[20116]],[[12933,12933],\\\"mapped\\\",[20845]],[[12934,12934],\\\"mapped\\\",[19971]],[[12935,12935],\\\"mapped\\\",[20843]],[[12936,12936],\\\"mapped\\\",[20061]],[[12937,12937],\\\"mapped\\\",[21313]],[[12938,12938],\\\"mapped\\\",[26376]],[[12939,12939],\\\"mapped\\\",[28779]],[[12940,12940],\\\"mapped\\\",[27700]],[[12941,12941],\\\"mapped\\\",[26408]],[[12942,12942],\\\"mapped\\\",[37329]],[[12943,12943],\\\"mapped\\\",[22303]],[[12944,12944],\\\"mapped\\\",[26085]],[[12945,12945],\\\"mapped\\\",[26666]],[[12946,12946],\\\"mapped\\\",[26377]],[[12947,12947],\\\"mapped\\\",[31038]],[[12948,12948],\\\"mapped\\\",[21517]],[[12949,12949],\\\"mapped\\\",[29305]],[[12950,12950],\\\"mapped\\\",[36001]],[[12951,12951],\\\"mapped\\\",[31069]],[[12952,12952],\\\"mapped\\\",[21172]],[[12953,12953],\\\"mapped\\\",[31192]],[[12954,12954],\\\"mapped\\\",[30007]],[[12955,12955],\\\"mapped\\\",[22899]],[[12956,12956],\\\"mapped\\\",[36969]],[[12957,12957],\\\"mapped\\\",[20778]],[[12958,12958],\\\"mapped\\\",[21360]],[[12959,12959],\\\"mapped\\\",[27880]],[[12960,12960],\\\"mapped\\\",[38917]],[[12961,12961],\\\"mapped\\\",[20241]],[[12962,12962],\\\"mapped\\\",[20889]],[[12963,12963],\\\"mapped\\\",[27491]],[[12964,12964],\\\"mapped\\\",[19978]],[[12965,12965],\\\"mapped\\\",[20013]],[[12966,12966],\\\"mapped\\\",[19979]],[[12967,12967],\\\"mapped\\\",[24038]],[[12968,12968],\\\"mapped\\\",[21491]],[[12969,12969],\\\"mapped\\\",[21307]],[[12970,12970],\\\"mapped\\\",[23447]],[[12971,12971],\\\"mapped\\\",[23398]],[[12972,12972],\\\"mapped\\\",[30435]],[[12973,12973],\\\"mapped\\\",[20225]],[[12974,12974],\\\"mapped\\\",[36039]],[[12975,12975],\\\"mapped\\\",[21332]],[[12976,12976],\\\"mapped\\\",[22812]],[[12977,12977],\\\"mapped\\\",[51,54]],[[12978,12978],\\\"mapped\\\",[51,55]],[[12979,12979],\\\"mapped\\\",[51,56]],[[12980,12980],\\\"mapped\\\",[51,57]],[[12981,12981],\\\"mapped\\\",[52,48]],[[12982,12982],\\\"mapped\\\",[52,49]],[[12983,12983],\\\"mapped\\\",[52,50]],[[12984,12984],\\\"mapped\\\",[52,51]],[[12985,12985],\\\"mapped\\\",[52,52]],[[12986,12986],\\\"mapped\\\",[52,53]],[[12987,12987],\\\"mapped\\\",[52,54]],[[12988,12988],\\\"mapped\\\",[52,55]],[[12989,12989],\\\"mapped\\\",[52,56]],[[12990,12990],\\\"mapped\\\",[52,57]],[[12991,12991],\\\"mapped\\\",[53,48]],[[12992,12992],\\\"mapped\\\",[49,26376]],[[12993,12993],\\\"mapped\\\",[50,26376]],[[12994,12994],\\\"mapped\\\",[51,26376]],[[12995,12995],\\\"mapped\\\",[52,26376]],[[12996,12996],\\\"mapped\\\",[53,26376]],[[12997,12997],\\\"mapped\\\",[54,26376]],[[12998,12998],\\\"mapped\\\",[55,26376]],[[12999,12999],\\\"mapped\\\",[56,26376]],[[13000,13000],\\\"mapped\\\",[57,26376]],[[13001,13001],\\\"mapped\\\",[49,48,26376]],[[13002,13002],\\\"mapped\\\",[49,49,26376]],[[13003,13003],\\\"mapped\\\",[49,50,26376]],[[13004,13004],\\\"mapped\\\",[104,103]],[[13005,13005],\\\"mapped\\\",[101,114,103]],[[13006,13006],\\\"mapped\\\",[101,118]],[[13007,13007],\\\"mapped\\\",[108,116,100]],[[13008,13008],\\\"mapped\\\",[12450]],[[13009,13009],\\\"mapped\\\",[12452]],[[13010,13010],\\\"mapped\\\",[12454]],[[13011,13011],\\\"mapped\\\",[12456]],[[13012,13012],\\\"mapped\\\",[12458]],[[13013,13013],\\\"mapped\\\",[12459]],[[13014,13014],\\\"mapped\\\",[12461]],[[13015,13015],\\\"mapped\\\",[12463]],[[13016,13016],\\\"mapped\\\",[12465]],[[13017,13017],\\\"mapped\\\",[12467]],[[13018,13018],\\\"mapped\\\",[12469]],[[13019,13019],\\\"mapped\\\",[12471]],[[13020,13020],\\\"mapped\\\",[12473]],[[13021,13021],\\\"mapped\\\",[12475]],[[13022,13022],\\\"mapped\\\",[12477]],[[13023,13023],\\\"mapped\\\",[12479]],[[13024,13024],\\\"mapped\\\",[12481]],[[13025,13025],\\\"mapped\\\",[12484]],[[13026,13026],\\\"mapped\\\",[12486]],[[13027,13027],\\\"mapped\\\",[12488]],[[13028,13028],\\\"mapped\\\",[12490]],[[13029,13029],\\\"mapped\\\",[12491]],[[13030,13030],\\\"mapped\\\",[12492]],[[13031,13031],\\\"mapped\\\",[12493]],[[13032,13032],\\\"mapped\\\",[12494]],[[13033,13033],\\\"mapped\\\",[12495]],[[13034,13034],\\\"mapped\\\",[12498]],[[13035,13035],\\\"mapped\\\",[12501]],[[13036,13036],\\\"mapped\\\",[12504]],[[13037,13037],\\\"mapped\\\",[12507]],[[13038,13038],\\\"mapped\\\",[12510]],[[13039,13039],\\\"mapped\\\",[12511]],[[13040,13040],\\\"mapped\\\",[12512]],[[13041,13041],\\\"mapped\\\",[12513]],[[13042,13042],\\\"mapped\\\",[12514]],[[13043,13043],\\\"mapped\\\",[12516]],[[13044,13044],\\\"mapped\\\",[12518]],[[13045,13045],\\\"mapped\\\",[12520]],[[13046,13046],\\\"mapped\\\",[12521]],[[13047,13047],\\\"mapped\\\",[12522]],[[13048,13048],\\\"mapped\\\",[12523]],[[13049,13049],\\\"mapped\\\",[12524]],[[13050,13050],\\\"mapped\\\",[12525]],[[13051,13051],\\\"mapped\\\",[12527]],[[13052,13052],\\\"mapped\\\",[12528]],[[13053,13053],\\\"mapped\\\",[12529]],[[13054,13054],\\\"mapped\\\",[12530]],[[13055,13055],\\\"disallowed\\\"],[[13056,13056],\\\"mapped\\\",[12450,12497,12540,12488]],[[13057,13057],\\\"mapped\\\",[12450,12523,12501,12449]],[[13058,13058],\\\"mapped\\\",[12450,12531,12506,12450]],[[13059,13059],\\\"mapped\\\",[12450,12540,12523]],[[13060,13060],\\\"mapped\\\",[12452,12491,12531,12464]],[[13061,13061],\\\"mapped\\\",[12452,12531,12481]],[[13062,13062],\\\"mapped\\\",[12454,12457,12531]],[[13063,13063],\\\"mapped\\\",[12456,12473,12463,12540,12489]],[[13064,13064],\\\"mapped\\\",[12456,12540,12459,12540]],[[13065,13065],\\\"mapped\\\",[12458,12531,12473]],[[13066,13066],\\\"mapped\\\",[12458,12540,12512]],[[13067,13067],\\\"mapped\\\",[12459,12452,12522]],[[13068,13068],\\\"mapped\\\",[12459,12521,12483,12488]],[[13069,13069],\\\"mapped\\\",[12459,12525,12522,12540]],[[13070,13070],\\\"mapped\\\",[12460,12525,12531]],[[13071,13071],\\\"mapped\\\",[12460,12531,12510]],[[13072,13072],\\\"mapped\\\",[12462,12460]],[[13073,13073],\\\"mapped\\\",[12462,12491,12540]],[[13074,13074],\\\"mapped\\\",[12461,12517,12522,12540]],[[13075,13075],\\\"mapped\\\",[12462,12523,12480,12540]],[[13076,13076],\\\"mapped\\\",[12461,12525]],[[13077,13077],\\\"mapped\\\",[12461,12525,12464,12521,12512]],[[13078,13078],\\\"mapped\\\",[12461,12525,12513,12540,12488,12523]],[[13079,13079],\\\"mapped\\\",[12461,12525,12527,12483,12488]],[[13080,13080],\\\"mapped\\\",[12464,12521,12512]],[[13081,13081],\\\"mapped\\\",[12464,12521,12512,12488,12531]],[[13082,13082],\\\"mapped\\\",[12463,12523,12476,12452,12525]],[[13083,13083],\\\"mapped\\\",[12463,12525,12540,12493]],[[13084,13084],\\\"mapped\\\",[12465,12540,12473]],[[13085,13085],\\\"mapped\\\",[12467,12523,12490]],[[13086,13086],\\\"mapped\\\",[12467,12540,12509]],[[13087,13087],\\\"mapped\\\",[12469,12452,12463,12523]],[[13088,13088],\\\"mapped\\\",[12469,12531,12481,12540,12512]],[[13089,13089],\\\"mapped\\\",[12471,12522,12531,12464]],[[13090,13090],\\\"mapped\\\",[12475,12531,12481]],[[13091,13091],\\\"mapped\\\",[12475,12531,12488]],[[13092,13092],\\\"mapped\\\",[12480,12540,12473]],[[13093,13093],\\\"mapped\\\",[12487,12471]],[[13094,13094],\\\"mapped\\\",[12489,12523]],[[13095,13095],\\\"mapped\\\",[12488,12531]],[[13096,13096],\\\"mapped\\\",[12490,12494]],[[13097,13097],\\\"mapped\\\",[12494,12483,12488]],[[13098,13098],\\\"mapped\\\",[12495,12452,12484]],[[13099,13099],\\\"mapped\\\",[12497,12540,12475,12531,12488]],[[13100,13100],\\\"mapped\\\",[12497,12540,12484]],[[13101,13101],\\\"mapped\\\",[12496,12540,12524,12523]],[[13102,13102],\\\"mapped\\\",[12500,12450,12473,12488,12523]],[[13103,13103],\\\"mapped\\\",[12500,12463,12523]],[[13104,13104],\\\"mapped\\\",[12500,12467]],[[13105,13105],\\\"mapped\\\",[12499,12523]],[[13106,13106],\\\"mapped\\\",[12501,12449,12521,12483,12489]],[[13107,13107],\\\"mapped\\\",[12501,12451,12540,12488]],[[13108,13108],\\\"mapped\\\",[12502,12483,12471,12455,12523]],[[13109,13109],\\\"mapped\\\",[12501,12521,12531]],[[13110,13110],\\\"mapped\\\",[12504,12463,12479,12540,12523]],[[13111,13111],\\\"mapped\\\",[12506,12477]],[[13112,13112],\\\"mapped\\\",[12506,12491,12498]],[[13113,13113],\\\"mapped\\\",[12504,12523,12484]],[[13114,13114],\\\"mapped\\\",[12506,12531,12473]],[[13115,13115],\\\"mapped\\\",[12506,12540,12472]],[[13116,13116],\\\"mapped\\\",[12505,12540,12479]],[[13117,13117],\\\"mapped\\\",[12509,12452,12531,12488]],[[13118,13118],\\\"mapped\\\",[12508,12523,12488]],[[13119,13119],\\\"mapped\\\",[12507,12531]],[[13120,13120],\\\"mapped\\\",[12509,12531,12489]],[[13121,13121],\\\"mapped\\\",[12507,12540,12523]],[[13122,13122],\\\"mapped\\\",[12507,12540,12531]],[[13123,13123],\\\"mapped\\\",[12510,12452,12463,12525]],[[13124,13124],\\\"mapped\\\",[12510,12452,12523]],[[13125,13125],\\\"mapped\\\",[12510,12483,12495]],[[13126,13126],\\\"mapped\\\",[12510,12523,12463]],[[13127,13127],\\\"mapped\\\",[12510,12531,12471,12519,12531]],[[13128,13128],\\\"mapped\\\",[12511,12463,12525,12531]],[[13129,13129],\\\"mapped\\\",[12511,12522]],[[13130,13130],\\\"mapped\\\",[12511,12522,12496,12540,12523]],[[13131,13131],\\\"mapped\\\",[12513,12460]],[[13132,13132],\\\"mapped\\\",[12513,12460,12488,12531]],[[13133,13133],\\\"mapped\\\",[12513,12540,12488,12523]],[[13134,13134],\\\"mapped\\\",[12516,12540,12489]],[[13135,13135],\\\"mapped\\\",[12516,12540,12523]],[[13136,13136],\\\"mapped\\\",[12518,12450,12531]],[[13137,13137],\\\"mapped\\\",[12522,12483,12488,12523]],[[13138,13138],\\\"mapped\\\",[12522,12521]],[[13139,13139],\\\"mapped\\\",[12523,12500,12540]],[[13140,13140],\\\"mapped\\\",[12523,12540,12502,12523]],[[13141,13141],\\\"mapped\\\",[12524,12512]],[[13142,13142],\\\"mapped\\\",[12524,12531,12488,12466,12531]],[[13143,13143],\\\"mapped\\\",[12527,12483,12488]],[[13144,13144],\\\"mapped\\\",[48,28857]],[[13145,13145],\\\"mapped\\\",[49,28857]],[[13146,13146],\\\"mapped\\\",[50,28857]],[[13147,13147],\\\"mapped\\\",[51,28857]],[[13148,13148],\\\"mapped\\\",[52,28857]],[[13149,13149],\\\"mapped\\\",[53,28857]],[[13150,13150],\\\"mapped\\\",[54,28857]],[[13151,13151],\\\"mapped\\\",[55,28857]],[[13152,13152],\\\"mapped\\\",[56,28857]],[[13153,13153],\\\"mapped\\\",[57,28857]],[[13154,13154],\\\"mapped\\\",[49,48,28857]],[[13155,13155],\\\"mapped\\\",[49,49,28857]],[[13156,13156],\\\"mapped\\\",[49,50,28857]],[[13157,13157],\\\"mapped\\\",[49,51,28857]],[[13158,13158],\\\"mapped\\\",[49,52,28857]],[[13159,13159],\\\"mapped\\\",[49,53,28857]],[[13160,13160],\\\"mapped\\\",[49,54,28857]],[[13161,13161],\\\"mapped\\\",[49,55,28857]],[[13162,13162],\\\"mapped\\\",[49,56,28857]],[[13163,13163],\\\"mapped\\\",[49,57,28857]],[[13164,13164],\\\"mapped\\\",[50,48,28857]],[[13165,13165],\\\"mapped\\\",[50,49,28857]],[[13166,13166],\\\"mapped\\\",[50,50,28857]],[[13167,13167],\\\"mapped\\\",[50,51,28857]],[[13168,13168],\\\"mapped\\\",[50,52,28857]],[[13169,13169],\\\"mapped\\\",[104,112,97]],[[13170,13170],\\\"mapped\\\",[100,97]],[[13171,13171],\\\"mapped\\\",[97,117]],[[13172,13172],\\\"mapped\\\",[98,97,114]],[[13173,13173],\\\"mapped\\\",[111,118]],[[13174,13174],\\\"mapped\\\",[112,99]],[[13175,13175],\\\"mapped\\\",[100,109]],[[13176,13176],\\\"mapped\\\",[100,109,50]],[[13177,13177],\\\"mapped\\\",[100,109,51]],[[13178,13178],\\\"mapped\\\",[105,117]],[[13179,13179],\\\"mapped\\\",[24179,25104]],[[13180,13180],\\\"mapped\\\",[26157,21644]],[[13181,13181],\\\"mapped\\\",[22823,27491]],[[13182,13182],\\\"mapped\\\",[26126,27835]],[[13183,13183],\\\"mapped\\\",[26666,24335,20250,31038]],[[13184,13184],\\\"mapped\\\",[112,97]],[[13185,13185],\\\"mapped\\\",[110,97]],[[13186,13186],\\\"mapped\\\",[956,97]],[[13187,13187],\\\"mapped\\\",[109,97]],[[13188,13188],\\\"mapped\\\",[107,97]],[[13189,13189],\\\"mapped\\\",[107,98]],[[13190,13190],\\\"mapped\\\",[109,98]],[[13191,13191],\\\"mapped\\\",[103,98]],[[13192,13192],\\\"mapped\\\",[99,97,108]],[[13193,13193],\\\"mapped\\\",[107,99,97,108]],[[13194,13194],\\\"mapped\\\",[112,102]],[[13195,13195],\\\"mapped\\\",[110,102]],[[13196,13196],\\\"mapped\\\",[956,102]],[[13197,13197],\\\"mapped\\\",[956,103]],[[13198,13198],\\\"mapped\\\",[109,103]],[[13199,13199],\\\"mapped\\\",[107,103]],[[13200,13200],\\\"mapped\\\",[104,122]],[[13201,13201],\\\"mapped\\\",[107,104,122]],[[13202,13202],\\\"mapped\\\",[109,104,122]],[[13203,13203],\\\"mapped\\\",[103,104,122]],[[13204,13204],\\\"mapped\\\",[116,104,122]],[[13205,13205],\\\"mapped\\\",[956,108]],[[13206,13206],\\\"mapped\\\",[109,108]],[[13207,13207],\\\"mapped\\\",[100,108]],[[13208,13208],\\\"mapped\\\",[107,108]],[[13209,13209],\\\"mapped\\\",[102,109]],[[13210,13210],\\\"mapped\\\",[110,109]],[[13211,13211],\\\"mapped\\\",[956,109]],[[13212,13212],\\\"mapped\\\",[109,109]],[[13213,13213],\\\"mapped\\\",[99,109]],[[13214,13214],\\\"mapped\\\",[107,109]],[[13215,13215],\\\"mapped\\\",[109,109,50]],[[13216,13216],\\\"mapped\\\",[99,109,50]],[[13217,13217],\\\"mapped\\\",[109,50]],[[13218,13218],\\\"mapped\\\",[107,109,50]],[[13219,13219],\\\"mapped\\\",[109,109,51]],[[13220,13220],\\\"mapped\\\",[99,109,51]],[[13221,13221],\\\"mapped\\\",[109,51]],[[13222,13222],\\\"mapped\\\",[107,109,51]],[[13223,13223],\\\"mapped\\\",[109,8725,115]],[[13224,13224],\\\"mapped\\\",[109,8725,115,50]],[[13225,13225],\\\"mapped\\\",[112,97]],[[13226,13226],\\\"mapped\\\",[107,112,97]],[[13227,13227],\\\"mapped\\\",[109,112,97]],[[13228,13228],\\\"mapped\\\",[103,112,97]],[[13229,13229],\\\"mapped\\\",[114,97,100]],[[13230,13230],\\\"mapped\\\",[114,97,100,8725,115]],[[13231,13231],\\\"mapped\\\",[114,97,100,8725,115,50]],[[13232,13232],\\\"mapped\\\",[112,115]],[[13233,13233],\\\"mapped\\\",[110,115]],[[13234,13234],\\\"mapped\\\",[956,115]],[[13235,13235],\\\"mapped\\\",[109,115]],[[13236,13236],\\\"mapped\\\",[112,118]],[[13237,13237],\\\"mapped\\\",[110,118]],[[13238,13238],\\\"mapped\\\",[956,118]],[[13239,13239],\\\"mapped\\\",[109,118]],[[13240,13240],\\\"mapped\\\",[107,118]],[[13241,13241],\\\"mapped\\\",[109,118]],[[13242,13242],\\\"mapped\\\",[112,119]],[[13243,13243],\\\"mapped\\\",[110,119]],[[13244,13244],\\\"mapped\\\",[956,119]],[[13245,13245],\\\"mapped\\\",[109,119]],[[13246,13246],\\\"mapped\\\",[107,119]],[[13247,13247],\\\"mapped\\\",[109,119]],[[13248,13248],\\\"mapped\\\",[107,969]],[[13249,13249],\\\"mapped\\\",[109,969]],[[13250,13250],\\\"disallowed\\\"],[[13251,13251],\\\"mapped\\\",[98,113]],[[13252,13252],\\\"mapped\\\",[99,99]],[[13253,13253],\\\"mapped\\\",[99,100]],[[13254,13254],\\\"mapped\\\",[99,8725,107,103]],[[13255,13255],\\\"disallowed\\\"],[[13256,13256],\\\"mapped\\\",[100,98]],[[13257,13257],\\\"mapped\\\",[103,121]],[[13258,13258],\\\"mapped\\\",[104,97]],[[13259,13259],\\\"mapped\\\",[104,112]],[[13260,13260],\\\"mapped\\\",[105,110]],[[13261,13261],\\\"mapped\\\",[107,107]],[[13262,13262],\\\"mapped\\\",[107,109]],[[13263,13263],\\\"mapped\\\",[107,116]],[[13264,13264],\\\"mapped\\\",[108,109]],[[13265,13265],\\\"mapped\\\",[108,110]],[[13266,13266],\\\"mapped\\\",[108,111,103]],[[13267,13267],\\\"mapped\\\",[108,120]],[[13268,13268],\\\"mapped\\\",[109,98]],[[13269,13269],\\\"mapped\\\",[109,105,108]],[[13270,13270],\\\"mapped\\\",[109,111,108]],[[13271,13271],\\\"mapped\\\",[112,104]],[[13272,13272],\\\"disallowed\\\"],[[13273,13273],\\\"mapped\\\",[112,112,109]],[[13274,13274],\\\"mapped\\\",[112,114]],[[13275,13275],\\\"mapped\\\",[115,114]],[[13276,13276],\\\"mapped\\\",[115,118]],[[13277,13277],\\\"mapped\\\",[119,98]],[[13278,13278],\\\"mapped\\\",[118,8725,109]],[[13279,13279],\\\"mapped\\\",[97,8725,109]],[[13280,13280],\\\"mapped\\\",[49,26085]],[[13281,13281],\\\"mapped\\\",[50,26085]],[[13282,13282],\\\"mapped\\\",[51,26085]],[[13283,13283],\\\"mapped\\\",[52,26085]],[[13284,13284],\\\"mapped\\\",[53,26085]],[[13285,13285],\\\"mapped\\\",[54,26085]],[[13286,13286],\\\"mapped\\\",[55,26085]],[[13287,13287],\\\"mapped\\\",[56,26085]],[[13288,13288],\\\"mapped\\\",[57,26085]],[[13289,13289],\\\"mapped\\\",[49,48,26085]],[[13290,13290],\\\"mapped\\\",[49,49,26085]],[[13291,13291],\\\"mapped\\\",[49,50,26085]],[[13292,13292],\\\"mapped\\\",[49,51,26085]],[[13293,13293],\\\"mapped\\\",[49,52,26085]],[[13294,13294],\\\"mapped\\\",[49,53,26085]],[[13295,13295],\\\"mapped\\\",[49,54,26085]],[[13296,13296],\\\"mapped\\\",[49,55,26085]],[[13297,13297],\\\"mapped\\\",[49,56,26085]],[[13298,13298],\\\"mapped\\\",[49,57,26085]],[[13299,13299],\\\"mapped\\\",[50,48,26085]],[[13300,13300],\\\"mapped\\\",[50,49,26085]],[[13301,13301],\\\"mapped\\\",[50,50,26085]],[[13302,13302],\\\"mapped\\\",[50,51,26085]],[[13303,13303],\\\"mapped\\\",[50,52,26085]],[[13304,13304],\\\"mapped\\\",[50,53,26085]],[[13305,13305],\\\"mapped\\\",[50,54,26085]],[[13306,13306],\\\"mapped\\\",[50,55,26085]],[[13307,13307],\\\"mapped\\\",[50,56,26085]],[[13308,13308],\\\"mapped\\\",[50,57,26085]],[[13309,13309],\\\"mapped\\\",[51,48,26085]],[[13310,13310],\\\"mapped\\\",[51,49,26085]],[[13311,13311],\\\"mapped\\\",[103,97,108]],[[13312,19893],\\\"valid\\\"],[[19894,19903],\\\"disallowed\\\"],[[19904,19967],\\\"valid\\\",[],\\\"NV8\\\"],[[19968,40869],\\\"valid\\\"],[[40870,40891],\\\"valid\\\"],[[40892,40899],\\\"valid\\\"],[[40900,40907],\\\"valid\\\"],[[40908,40908],\\\"valid\\\"],[[40909,40917],\\\"valid\\\"],[[40918,40959],\\\"disallowed\\\"],[[40960,42124],\\\"valid\\\"],[[42125,42127],\\\"disallowed\\\"],[[42128,42145],\\\"valid\\\",[],\\\"NV8\\\"],[[42146,42147],\\\"valid\\\",[],\\\"NV8\\\"],[[42148,42163],\\\"valid\\\",[],\\\"NV8\\\"],[[42164,42164],\\\"valid\\\",[],\\\"NV8\\\"],[[42165,42176],\\\"valid\\\",[],\\\"NV8\\\"],[[42177,42177],\\\"valid\\\",[],\\\"NV8\\\"],[[42178,42180],\\\"valid\\\",[],\\\"NV8\\\"],[[42181,42181],\\\"valid\\\",[],\\\"NV8\\\"],[[42182,42182],\\\"valid\\\",[],\\\"NV8\\\"],[[42183,42191],\\\"disallowed\\\"],[[42192,42237],\\\"valid\\\"],[[42238,42239],\\\"valid\\\",[],\\\"NV8\\\"],[[42240,42508],\\\"valid\\\"],[[42509,42511],\\\"valid\\\",[],\\\"NV8\\\"],[[42512,42539],\\\"valid\\\"],[[42540,42559],\\\"disallowed\\\"],[[42560,42560],\\\"mapped\\\",[42561]],[[42561,42561],\\\"valid\\\"],[[42562,42562],\\\"mapped\\\",[42563]],[[42563,42563],\\\"valid\\\"],[[42564,42564],\\\"mapped\\\",[42565]],[[42565,42565],\\\"valid\\\"],[[42566,42566],\\\"mapped\\\",[42567]],[[42567,42567],\\\"valid\\\"],[[42568,42568],\\\"mapped\\\",[42569]],[[42569,42569],\\\"valid\\\"],[[42570,42570],\\\"mapped\\\",[42571]],[[42571,42571],\\\"valid\\\"],[[42572,42572],\\\"mapped\\\",[42573]],[[42573,42573],\\\"valid\\\"],[[42574,42574],\\\"mapped\\\",[42575]],[[42575,42575],\\\"valid\\\"],[[42576,42576],\\\"mapped\\\",[42577]],[[42577,42577],\\\"valid\\\"],[[42578,42578],\\\"mapped\\\",[42579]],[[42579,42579],\\\"valid\\\"],[[42580,42580],\\\"mapped\\\",[42581]],[[42581,42581],\\\"valid\\\"],[[42582,42582],\\\"mapped\\\",[42583]],[[42583,42583],\\\"valid\\\"],[[42584,42584],\\\"mapped\\\",[42585]],[[42585,42585],\\\"valid\\\"],[[42586,42586],\\\"mapped\\\",[42587]],[[42587,42587],\\\"valid\\\"],[[42588,42588],\\\"mapped\\\",[42589]],[[42589,42589],\\\"valid\\\"],[[42590,42590],\\\"mapped\\\",[42591]],[[42591,42591],\\\"valid\\\"],[[42592,42592],\\\"mapped\\\",[42593]],[[42593,42593],\\\"valid\\\"],[[42594,42594],\\\"mapped\\\",[42595]],[[42595,42595],\\\"valid\\\"],[[42596,42596],\\\"mapped\\\",[42597]],[[42597,42597],\\\"valid\\\"],[[42598,42598],\\\"mapped\\\",[42599]],[[42599,42599],\\\"valid\\\"],[[42600,42600],\\\"mapped\\\",[42601]],[[42601,42601],\\\"valid\\\"],[[42602,42602],\\\"mapped\\\",[42603]],[[42603,42603],\\\"valid\\\"],[[42604,42604],\\\"mapped\\\",[42605]],[[42605,42607],\\\"valid\\\"],[[42608,42611],\\\"valid\\\",[],\\\"NV8\\\"],[[42612,42619],\\\"valid\\\"],[[42620,42621],\\\"valid\\\"],[[42622,42622],\\\"valid\\\",[],\\\"NV8\\\"],[[42623,42623],\\\"valid\\\"],[[42624,42624],\\\"mapped\\\",[42625]],[[42625,42625],\\\"valid\\\"],[[42626,42626],\\\"mapped\\\",[42627]],[[42627,42627],\\\"valid\\\"],[[42628,42628],\\\"mapped\\\",[42629]],[[42629,42629],\\\"valid\\\"],[[42630,42630],\\\"mapped\\\",[42631]],[[42631,42631],\\\"valid\\\"],[[42632,42632],\\\"mapped\\\",[42633]],[[42633,42633],\\\"valid\\\"],[[42634,42634],\\\"mapped\\\",[42635]],[[42635,42635],\\\"valid\\\"],[[42636,42636],\\\"mapped\\\",[42637]],[[42637,42637],\\\"valid\\\"],[[42638,42638],\\\"mapped\\\",[42639]],[[42639,42639],\\\"valid\\\"],[[42640,42640],\\\"mapped\\\",[42641]],[[42641,42641],\\\"valid\\\"],[[42642,42642],\\\"mapped\\\",[42643]],[[42643,42643],\\\"valid\\\"],[[42644,42644],\\\"mapped\\\",[42645]],[[42645,42645],\\\"valid\\\"],[[42646,42646],\\\"mapped\\\",[42647]],[[42647,42647],\\\"valid\\\"],[[42648,42648],\\\"mapped\\\",[42649]],[[42649,42649],\\\"valid\\\"],[[42650,42650],\\\"mapped\\\",[42651]],[[42651,42651],\\\"valid\\\"],[[42652,42652],\\\"mapped\\\",[1098]],[[42653,42653],\\\"mapped\\\",[1100]],[[42654,42654],\\\"valid\\\"],[[42655,42655],\\\"valid\\\"],[[42656,42725],\\\"valid\\\"],[[42726,42735],\\\"valid\\\",[],\\\"NV8\\\"],[[42736,42737],\\\"valid\\\"],[[42738,42743],\\\"valid\\\",[],\\\"NV8\\\"],[[42744,42751],\\\"disallowed\\\"],[[42752,42774],\\\"valid\\\",[],\\\"NV8\\\"],[[42775,42778],\\\"valid\\\"],[[42779,42783],\\\"valid\\\"],[[42784,42785],\\\"valid\\\",[],\\\"NV8\\\"],[[42786,42786],\\\"mapped\\\",[42787]],[[42787,42787],\\\"valid\\\"],[[42788,42788],\\\"mapped\\\",[42789]],[[42789,42789],\\\"valid\\\"],[[42790,42790],\\\"mapped\\\",[42791]],[[42791,42791],\\\"valid\\\"],[[42792,42792],\\\"mapped\\\",[42793]],[[42793,42793],\\\"valid\\\"],[[42794,42794],\\\"mapped\\\",[42795]],[[42795,42795],\\\"valid\\\"],[[42796,42796],\\\"mapped\\\",[42797]],[[42797,42797],\\\"valid\\\"],[[42798,42798],\\\"mapped\\\",[42799]],[[42799,42801],\\\"valid\\\"],[[42802,42802],\\\"mapped\\\",[42803]],[[42803,42803],\\\"valid\\\"],[[42804,42804],\\\"mapped\\\",[42805]],[[42805,42805],\\\"valid\\\"],[[42806,42806],\\\"mapped\\\",[42807]],[[42807,42807],\\\"valid\\\"],[[42808,42808],\\\"mapped\\\",[42809]],[[42809,42809],\\\"valid\\\"],[[42810,42810],\\\"mapped\\\",[42811]],[[42811,42811],\\\"valid\\\"],[[42812,42812],\\\"mapped\\\",[42813]],[[42813,42813],\\\"valid\\\"],[[42814,42814],\\\"mapped\\\",[42815]],[[42815,42815],\\\"valid\\\"],[[42816,42816],\\\"mapped\\\",[42817]],[[42817,42817],\\\"valid\\\"],[[42818,42818],\\\"mapped\\\",[42819]],[[42819,42819],\\\"valid\\\"],[[42820,42820],\\\"mapped\\\",[42821]],[[42821,42821],\\\"valid\\\"],[[42822,42822],\\\"mapped\\\",[42823]],[[42823,42823],\\\"valid\\\"],[[42824,42824],\\\"mapped\\\",[42825]],[[42825,42825],\\\"valid\\\"],[[42826,42826],\\\"mapped\\\",[42827]],[[42827,42827],\\\"valid\\\"],[[42828,42828],\\\"mapped\\\",[42829]],[[42829,42829],\\\"valid\\\"],[[42830,42830],\\\"mapped\\\",[42831]],[[42831,42831],\\\"valid\\\"],[[42832,42832],\\\"mapped\\\",[42833]],[[42833,42833],\\\"valid\\\"],[[42834,42834],\\\"mapped\\\",[42835]],[[42835,42835],\\\"valid\\\"],[[42836,42836],\\\"mapped\\\",[42837]],[[42837,42837],\\\"valid\\\"],[[42838,42838],\\\"mapped\\\",[42839]],[[42839,42839],\\\"valid\\\"],[[42840,42840],\\\"mapped\\\",[42841]],[[42841,42841],\\\"valid\\\"],[[42842,42842],\\\"mapped\\\",[42843]],[[42843,42843],\\\"valid\\\"],[[42844,42844],\\\"mapped\\\",[42845]],[[42845,42845],\\\"valid\\\"],[[42846,42846],\\\"mapped\\\",[42847]],[[42847,42847],\\\"valid\\\"],[[42848,42848],\\\"mapped\\\",[42849]],[[42849,42849],\\\"valid\\\"],[[42850,42850],\\\"mapped\\\",[42851]],[[42851,42851],\\\"valid\\\"],[[42852,42852],\\\"mapped\\\",[42853]],[[42853,42853],\\\"valid\\\"],[[42854,42854],\\\"mapped\\\",[42855]],[[42855,42855],\\\"valid\\\"],[[42856,42856],\\\"mapped\\\",[42857]],[[42857,42857],\\\"valid\\\"],[[42858,42858],\\\"mapped\\\",[42859]],[[42859,42859],\\\"valid\\\"],[[42860,42860],\\\"mapped\\\",[42861]],[[42861,42861],\\\"valid\\\"],[[42862,42862],\\\"mapped\\\",[42863]],[[42863,42863],\\\"valid\\\"],[[42864,42864],\\\"mapped\\\",[42863]],[[42865,42872],\\\"valid\\\"],[[42873,42873],\\\"mapped\\\",[42874]],[[42874,42874],\\\"valid\\\"],[[42875,42875],\\\"mapped\\\",[42876]],[[42876,42876],\\\"valid\\\"],[[42877,42877],\\\"mapped\\\",[7545]],[[42878,42878],\\\"mapped\\\",[42879]],[[42879,42879],\\\"valid\\\"],[[42880,42880],\\\"mapped\\\",[42881]],[[42881,42881],\\\"valid\\\"],[[42882,42882],\\\"mapped\\\",[42883]],[[42883,42883],\\\"valid\\\"],[[42884,42884],\\\"mapped\\\",[42885]],[[42885,42885],\\\"valid\\\"],[[42886,42886],\\\"mapped\\\",[42887]],[[42887,42888],\\\"valid\\\"],[[42889,42890],\\\"valid\\\",[],\\\"NV8\\\"],[[42891,42891],\\\"mapped\\\",[42892]],[[42892,42892],\\\"valid\\\"],[[42893,42893],\\\"mapped\\\",[613]],[[42894,42894],\\\"valid\\\"],[[42895,42895],\\\"valid\\\"],[[42896,42896],\\\"mapped\\\",[42897]],[[42897,42897],\\\"valid\\\"],[[42898,42898],\\\"mapped\\\",[42899]],[[42899,42899],\\\"valid\\\"],[[42900,42901],\\\"valid\\\"],[[42902,42902],\\\"mapped\\\",[42903]],[[42903,42903],\\\"valid\\\"],[[42904,42904],\\\"mapped\\\",[42905]],[[42905,42905],\\\"valid\\\"],[[42906,42906],\\\"mapped\\\",[42907]],[[42907,42907],\\\"valid\\\"],[[42908,42908],\\\"mapped\\\",[42909]],[[42909,42909],\\\"valid\\\"],[[42910,42910],\\\"mapped\\\",[42911]],[[42911,42911],\\\"valid\\\"],[[42912,42912],\\\"mapped\\\",[42913]],[[42913,42913],\\\"valid\\\"],[[42914,42914],\\\"mapped\\\",[42915]],[[42915,42915],\\\"valid\\\"],[[42916,42916],\\\"mapped\\\",[42917]],[[42917,42917],\\\"valid\\\"],[[42918,42918],\\\"mapped\\\",[42919]],[[42919,42919],\\\"valid\\\"],[[42920,42920],\\\"mapped\\\",[42921]],[[42921,42921],\\\"valid\\\"],[[42922,42922],\\\"mapped\\\",[614]],[[42923,42923],\\\"mapped\\\",[604]],[[42924,42924],\\\"mapped\\\",[609]],[[42925,42925],\\\"mapped\\\",[620]],[[42926,42927],\\\"disallowed\\\"],[[42928,42928],\\\"mapped\\\",[670]],[[42929,42929],\\\"mapped\\\",[647]],[[42930,42930],\\\"mapped\\\",[669]],[[42931,42931],\\\"mapped\\\",[43859]],[[42932,42932],\\\"mapped\\\",[42933]],[[42933,42933],\\\"valid\\\"],[[42934,42934],\\\"mapped\\\",[42935]],[[42935,42935],\\\"valid\\\"],[[42936,42998],\\\"disallowed\\\"],[[42999,42999],\\\"valid\\\"],[[43000,43000],\\\"mapped\\\",[295]],[[43001,43001],\\\"mapped\\\",[339]],[[43002,43002],\\\"valid\\\"],[[43003,43007],\\\"valid\\\"],[[43008,43047],\\\"valid\\\"],[[43048,43051],\\\"valid\\\",[],\\\"NV8\\\"],[[43052,43055],\\\"disallowed\\\"],[[43056,43065],\\\"valid\\\",[],\\\"NV8\\\"],[[43066,43071],\\\"disallowed\\\"],[[43072,43123],\\\"valid\\\"],[[43124,43127],\\\"valid\\\",[],\\\"NV8\\\"],[[43128,43135],\\\"disallowed\\\"],[[43136,43204],\\\"valid\\\"],[[43205,43213],\\\"disallowed\\\"],[[43214,43215],\\\"valid\\\",[],\\\"NV8\\\"],[[43216,43225],\\\"valid\\\"],[[43226,43231],\\\"disallowed\\\"],[[43232,43255],\\\"valid\\\"],[[43256,43258],\\\"valid\\\",[],\\\"NV8\\\"],[[43259,43259],\\\"valid\\\"],[[43260,43260],\\\"valid\\\",[],\\\"NV8\\\"],[[43261,43261],\\\"valid\\\"],[[43262,43263],\\\"disallowed\\\"],[[43264,43309],\\\"valid\\\"],[[43310,43311],\\\"valid\\\",[],\\\"NV8\\\"],[[43312,43347],\\\"valid\\\"],[[43348,43358],\\\"disallowed\\\"],[[43359,43359],\\\"valid\\\",[],\\\"NV8\\\"],[[43360,43388],\\\"valid\\\",[],\\\"NV8\\\"],[[43389,43391],\\\"disallowed\\\"],[[43392,43456],\\\"valid\\\"],[[43457,43469],\\\"valid\\\",[],\\\"NV8\\\"],[[43470,43470],\\\"disallowed\\\"],[[43471,43481],\\\"valid\\\"],[[43482,43485],\\\"disallowed\\\"],[[43486,43487],\\\"valid\\\",[],\\\"NV8\\\"],[[43488,43518],\\\"valid\\\"],[[43519,43519],\\\"disallowed\\\"],[[43520,43574],\\\"valid\\\"],[[43575,43583],\\\"disallowed\\\"],[[43584,43597],\\\"valid\\\"],[[43598,43599],\\\"disallowed\\\"],[[43600,43609],\\\"valid\\\"],[[43610,43611],\\\"disallowed\\\"],[[43612,43615],\\\"valid\\\",[],\\\"NV8\\\"],[[43616,43638],\\\"valid\\\"],[[43639,43641],\\\"valid\\\",[],\\\"NV8\\\"],[[43642,43643],\\\"valid\\\"],[[43644,43647],\\\"valid\\\"],[[43648,43714],\\\"valid\\\"],[[43715,43738],\\\"disallowed\\\"],[[43739,43741],\\\"valid\\\"],[[43742,43743],\\\"valid\\\",[],\\\"NV8\\\"],[[43744,43759],\\\"valid\\\"],[[43760,43761],\\\"valid\\\",[],\\\"NV8\\\"],[[43762,43766],\\\"valid\\\"],[[43767,43776],\\\"disallowed\\\"],[[43777,43782],\\\"valid\\\"],[[43783,43784],\\\"disallowed\\\"],[[43785,43790],\\\"valid\\\"],[[43791,43792],\\\"disallowed\\\"],[[43793,43798],\\\"valid\\\"],[[43799,43807],\\\"disallowed\\\"],[[43808,43814],\\\"valid\\\"],[[43815,43815],\\\"disallowed\\\"],[[43816,43822],\\\"valid\\\"],[[43823,43823],\\\"disallowed\\\"],[[43824,43866],\\\"valid\\\"],[[43867,43867],\\\"valid\\\",[],\\\"NV8\\\"],[[43868,43868],\\\"mapped\\\",[42791]],[[43869,43869],\\\"mapped\\\",[43831]],[[43870,43870],\\\"mapped\\\",[619]],[[43871,43871],\\\"mapped\\\",[43858]],[[43872,43875],\\\"valid\\\"],[[43876,43877],\\\"valid\\\"],[[43878,43887],\\\"disallowed\\\"],[[43888,43888],\\\"mapped\\\",[5024]],[[43889,43889],\\\"mapped\\\",[5025]],[[43890,43890],\\\"mapped\\\",[5026]],[[43891,43891],\\\"mapped\\\",[5027]],[[43892,43892],\\\"mapped\\\",[5028]],[[43893,43893],\\\"mapped\\\",[5029]],[[43894,43894],\\\"mapped\\\",[5030]],[[43895,43895],\\\"mapped\\\",[5031]],[[43896,43896],\\\"mapped\\\",[5032]],[[43897,43897],\\\"mapped\\\",[5033]],[[43898,43898],\\\"mapped\\\",[5034]],[[43899,43899],\\\"mapped\\\",[5035]],[[43900,43900],\\\"mapped\\\",[5036]],[[43901,43901],\\\"mapped\\\",[5037]],[[43902,43902],\\\"mapped\\\",[5038]],[[43903,43903],\\\"mapped\\\",[5039]],[[43904,43904],\\\"mapped\\\",[5040]],[[43905,43905],\\\"mapped\\\",[5041]],[[43906,43906],\\\"mapped\\\",[5042]],[[43907,43907],\\\"mapped\\\",[5043]],[[43908,43908],\\\"mapped\\\",[5044]],[[43909,43909],\\\"mapped\\\",[5045]],[[43910,43910],\\\"mapped\\\",[5046]],[[43911,43911],\\\"mapped\\\",[5047]],[[43912,43912],\\\"mapped\\\",[5048]],[[43913,43913],\\\"mapped\\\",[5049]],[[43914,43914],\\\"mapped\\\",[5050]],[[43915,43915],\\\"mapped\\\",[5051]],[[43916,43916],\\\"mapped\\\",[5052]],[[43917,43917],\\\"mapped\\\",[5053]],[[43918,43918],\\\"mapped\\\",[5054]],[[43919,43919],\\\"mapped\\\",[5055]],[[43920,43920],\\\"mapped\\\",[5056]],[[43921,43921],\\\"mapped\\\",[5057]],[[43922,43922],\\\"mapped\\\",[5058]],[[43923,43923],\\\"mapped\\\",[5059]],[[43924,43924],\\\"mapped\\\",[5060]],[[43925,43925],\\\"mapped\\\",[5061]],[[43926,43926],\\\"mapped\\\",[5062]],[[43927,43927],\\\"mapped\\\",[5063]],[[43928,43928],\\\"mapped\\\",[5064]],[[43929,43929],\\\"mapped\\\",[5065]],[[43930,43930],\\\"mapped\\\",[5066]],[[43931,43931],\\\"mapped\\\",[5067]],[[43932,43932],\\\"mapped\\\",[5068]],[[43933,43933],\\\"mapped\\\",[5069]],[[43934,43934],\\\"mapped\\\",[5070]],[[43935,43935],\\\"mapped\\\",[5071]],[[43936,43936],\\\"mapped\\\",[5072]],[[43937,43937],\\\"mapped\\\",[5073]],[[43938,43938],\\\"mapped\\\",[5074]],[[43939,43939],\\\"mapped\\\",[5075]],[[43940,43940],\\\"mapped\\\",[5076]],[[43941,43941],\\\"mapped\\\",[5077]],[[43942,43942],\\\"mapped\\\",[5078]],[[43943,43943],\\\"mapped\\\",[5079]],[[43944,43944],\\\"mapped\\\",[5080]],[[43945,43945],\\\"mapped\\\",[5081]],[[43946,43946],\\\"mapped\\\",[5082]],[[43947,43947],\\\"mapped\\\",[5083]],[[43948,43948],\\\"mapped\\\",[5084]],[[43949,43949],\\\"mapped\\\",[5085]],[[43950,43950],\\\"mapped\\\",[5086]],[[43951,43951],\\\"mapped\\\",[5087]],[[43952,43952],\\\"mapped\\\",[5088]],[[43953,43953],\\\"mapped\\\",[5089]],[[43954,43954],\\\"mapped\\\",[5090]],[[43955,43955],\\\"mapped\\\",[5091]],[[43956,43956],\\\"mapped\\\",[5092]],[[43957,43957],\\\"mapped\\\",[5093]],[[43958,43958],\\\"mapped\\\",[5094]],[[43959,43959],\\\"mapped\\\",[5095]],[[43960,43960],\\\"mapped\\\",[5096]],[[43961,43961],\\\"mapped\\\",[5097]],[[43962,43962],\\\"mapped\\\",[5098]],[[43963,43963],\\\"mapped\\\",[5099]],[[43964,43964],\\\"mapped\\\",[5100]],[[43965,43965],\\\"mapped\\\",[5101]],[[43966,43966],\\\"mapped\\\",[5102]],[[43967,43967],\\\"mapped\\\",[5103]],[[43968,44010],\\\"valid\\\"],[[44011,44011],\\\"valid\\\",[],\\\"NV8\\\"],[[44012,44013],\\\"valid\\\"],[[44014,44015],\\\"disallowed\\\"],[[44016,44025],\\\"valid\\\"],[[44026,44031],\\\"disallowed\\\"],[[44032,55203],\\\"valid\\\"],[[55204,55215],\\\"disallowed\\\"],[[55216,55238],\\\"valid\\\",[],\\\"NV8\\\"],[[55239,55242],\\\"disallowed\\\"],[[55243,55291],\\\"valid\\\",[],\\\"NV8\\\"],[[55292,55295],\\\"disallowed\\\"],[[55296,57343],\\\"disallowed\\\"],[[57344,63743],\\\"disallowed\\\"],[[63744,63744],\\\"mapped\\\",[35912]],[[63745,63745],\\\"mapped\\\",[26356]],[[63746,63746],\\\"mapped\\\",[36554]],[[63747,63747],\\\"mapped\\\",[36040]],[[63748,63748],\\\"mapped\\\",[28369]],[[63749,63749],\\\"mapped\\\",[20018]],[[63750,63750],\\\"mapped\\\",[21477]],[[63751,63752],\\\"mapped\\\",[40860]],[[63753,63753],\\\"mapped\\\",[22865]],[[63754,63754],\\\"mapped\\\",[37329]],[[63755,63755],\\\"mapped\\\",[21895]],[[63756,63756],\\\"mapped\\\",[22856]],[[63757,63757],\\\"mapped\\\",[25078]],[[63758,63758],\\\"mapped\\\",[30313]],[[63759,63759],\\\"mapped\\\",[32645]],[[63760,63760],\\\"mapped\\\",[34367]],[[63761,63761],\\\"mapped\\\",[34746]],[[63762,63762],\\\"mapped\\\",[35064]],[[63763,63763],\\\"mapped\\\",[37007]],[[63764,63764],\\\"mapped\\\",[27138]],[[63765,63765],\\\"mapped\\\",[27931]],[[63766,63766],\\\"mapped\\\",[28889]],[[63767,63767],\\\"mapped\\\",[29662]],[[63768,63768],\\\"mapped\\\",[33853]],[[63769,63769],\\\"mapped\\\",[37226]],[[63770,63770],\\\"mapped\\\",[39409]],[[63771,63771],\\\"mapped\\\",[20098]],[[63772,63772],\\\"mapped\\\",[21365]],[[63773,63773],\\\"mapped\\\",[27396]],[[63774,63774],\\\"mapped\\\",[29211]],[[63775,63775],\\\"mapped\\\",[34349]],[[63776,63776],\\\"mapped\\\",[40478]],[[63777,63777],\\\"mapped\\\",[23888]],[[63778,63778],\\\"mapped\\\",[28651]],[[63779,63779],\\\"mapped\\\",[34253]],[[63780,63780],\\\"mapped\\\",[35172]],[[63781,63781],\\\"mapped\\\",[25289]],[[63782,63782],\\\"mapped\\\",[33240]],[[63783,63783],\\\"mapped\\\",[34847]],[[63784,63784],\\\"mapped\\\",[24266]],[[63785,63785],\\\"mapped\\\",[26391]],[[63786,63786],\\\"mapped\\\",[28010]],[[63787,63787],\\\"mapped\\\",[29436]],[[63788,63788],\\\"mapped\\\",[37070]],[[63789,63789],\\\"mapped\\\",[20358]],[[63790,63790],\\\"mapped\\\",[20919]],[[63791,63791],\\\"mapped\\\",[21214]],[[63792,63792],\\\"mapped\\\",[25796]],[[63793,63793],\\\"mapped\\\",[27347]],[[63794,63794],\\\"mapped\\\",[29200]],[[63795,63795],\\\"mapped\\\",[30439]],[[63796,63796],\\\"mapped\\\",[32769]],[[63797,63797],\\\"mapped\\\",[34310]],[[63798,63798],\\\"mapped\\\",[34396]],[[63799,63799],\\\"mapped\\\",[36335]],[[63800,63800],\\\"mapped\\\",[38706]],[[63801,63801],\\\"mapped\\\",[39791]],[[63802,63802],\\\"mapped\\\",[40442]],[[63803,63803],\\\"mapped\\\",[30860]],[[63804,63804],\\\"mapped\\\",[31103]],[[63805,63805],\\\"mapped\\\",[32160]],[[63806,63806],\\\"mapped\\\",[33737]],[[63807,63807],\\\"mapped\\\",[37636]],[[63808,63808],\\\"mapped\\\",[40575]],[[63809,63809],\\\"mapped\\\",[35542]],[[63810,63810],\\\"mapped\\\",[22751]],[[63811,63811],\\\"mapped\\\",[24324]],[[63812,63812],\\\"mapped\\\",[31840]],[[63813,63813],\\\"mapped\\\",[32894]],[[63814,63814],\\\"mapped\\\",[29282]],[[63815,63815],\\\"mapped\\\",[30922]],[[63816,63816],\\\"mapped\\\",[36034]],[[63817,63817],\\\"mapped\\\",[38647]],[[63818,63818],\\\"mapped\\\",[22744]],[[63819,63819],\\\"mapped\\\",[23650]],[[63820,63820],\\\"mapped\\\",[27155]],[[63821,63821],\\\"mapped\\\",[28122]],[[63822,63822],\\\"mapped\\\",[28431]],[[63823,63823],\\\"mapped\\\",[32047]],[[63824,63824],\\\"mapped\\\",[32311]],[[63825,63825],\\\"mapped\\\",[38475]],[[63826,63826],\\\"mapped\\\",[21202]],[[63827,63827],\\\"mapped\\\",[32907]],[[63828,63828],\\\"mapped\\\",[20956]],[[63829,63829],\\\"mapped\\\",[20940]],[[63830,63830],\\\"mapped\\\",[31260]],[[63831,63831],\\\"mapped\\\",[32190]],[[63832,63832],\\\"mapped\\\",[33777]],[[63833,63833],\\\"mapped\\\",[38517]],[[63834,63834],\\\"mapped\\\",[35712]],[[63835,63835],\\\"mapped\\\",[25295]],[[63836,63836],\\\"mapped\\\",[27138]],[[63837,63837],\\\"mapped\\\",[35582]],[[63838,63838],\\\"mapped\\\",[20025]],[[63839,63839],\\\"mapped\\\",[23527]],[[63840,63840],\\\"mapped\\\",[24594]],[[63841,63841],\\\"mapped\\\",[29575]],[[63842,63842],\\\"mapped\\\",[30064]],[[63843,63843],\\\"mapped\\\",[21271]],[[63844,63844],\\\"mapped\\\",[30971]],[[63845,63845],\\\"mapped\\\",[20415]],[[63846,63846],\\\"mapped\\\",[24489]],[[63847,63847],\\\"mapped\\\",[19981]],[[63848,63848],\\\"mapped\\\",[27852]],[[63849,63849],\\\"mapped\\\",[25976]],[[63850,63850],\\\"mapped\\\",[32034]],[[63851,63851],\\\"mapped\\\",[21443]],[[63852,63852],\\\"mapped\\\",[22622]],[[63853,63853],\\\"mapped\\\",[30465]],[[63854,63854],\\\"mapped\\\",[33865]],[[63855,63855],\\\"mapped\\\",[35498]],[[63856,63856],\\\"mapped\\\",[27578]],[[63857,63857],\\\"mapped\\\",[36784]],[[63858,63858],\\\"mapped\\\",[27784]],[[63859,63859],\\\"mapped\\\",[25342]],[[63860,63860],\\\"mapped\\\",[33509]],[[63861,63861],\\\"mapped\\\",[25504]],[[63862,63862],\\\"mapped\\\",[30053]],[[63863,63863],\\\"mapped\\\",[20142]],[[63864,63864],\\\"mapped\\\",[20841]],[[63865,63865],\\\"mapped\\\",[20937]],[[63866,63866],\\\"mapped\\\",[26753]],[[63867,63867],\\\"mapped\\\",[31975]],[[63868,63868],\\\"mapped\\\",[33391]],[[63869,63869],\\\"mapped\\\",[35538]],[[63870,63870],\\\"mapped\\\",[37327]],[[63871,63871],\\\"mapped\\\",[21237]],[[63872,63872],\\\"mapped\\\",[21570]],[[63873,63873],\\\"mapped\\\",[22899]],[[63874,63874],\\\"mapped\\\",[24300]],[[63875,63875],\\\"mapped\\\",[26053]],[[63876,63876],\\\"mapped\\\",[28670]],[[63877,63877],\\\"mapped\\\",[31018]],[[63878,63878],\\\"mapped\\\",[38317]],[[63879,63879],\\\"mapped\\\",[39530]],[[63880,63880],\\\"mapped\\\",[40599]],[[63881,63881],\\\"mapped\\\",[40654]],[[63882,63882],\\\"mapped\\\",[21147]],[[63883,63883],\\\"mapped\\\",[26310]],[[63884,63884],\\\"mapped\\\",[27511]],[[63885,63885],\\\"mapped\\\",[36706]],[[63886,63886],\\\"mapped\\\",[24180]],[[63887,63887],\\\"mapped\\\",[24976]],[[63888,63888],\\\"mapped\\\",[25088]],[[63889,63889],\\\"mapped\\\",[25754]],[[63890,63890],\\\"mapped\\\",[28451]],[[63891,63891],\\\"mapped\\\",[29001]],[[63892,63892],\\\"mapped\\\",[29833]],[[63893,63893],\\\"mapped\\\",[31178]],[[63894,63894],\\\"mapped\\\",[32244]],[[63895,63895],\\\"mapped\\\",[32879]],[[63896,63896],\\\"mapped\\\",[36646]],[[63897,63897],\\\"mapped\\\",[34030]],[[63898,63898],\\\"mapped\\\",[36899]],[[63899,63899],\\\"mapped\\\",[37706]],[[63900,63900],\\\"mapped\\\",[21015]],[[63901,63901],\\\"mapped\\\",[21155]],[[63902,63902],\\\"mapped\\\",[21693]],[[63903,63903],\\\"mapped\\\",[28872]],[[63904,63904],\\\"mapped\\\",[35010]],[[63905,63905],\\\"mapped\\\",[35498]],[[63906,63906],\\\"mapped\\\",[24265]],[[63907,63907],\\\"mapped\\\",[24565]],[[63908,63908],\\\"mapped\\\",[25467]],[[63909,63909],\\\"mapped\\\",[27566]],[[63910,63910],\\\"mapped\\\",[31806]],[[63911,63911],\\\"mapped\\\",[29557]],[[63912,63912],\\\"mapped\\\",[20196]],[[63913,63913],\\\"mapped\\\",[22265]],[[63914,63914],\\\"mapped\\\",[23527]],[[63915,63915],\\\"mapped\\\",[23994]],[[63916,63916],\\\"mapped\\\",[24604]],[[63917,63917],\\\"mapped\\\",[29618]],[[63918,63918],\\\"mapped\\\",[29801]],[[63919,63919],\\\"mapped\\\",[32666]],[[63920,63920],\\\"mapped\\\",[32838]],[[63921,63921],\\\"mapped\\\",[37428]],[[63922,63922],\\\"mapped\\\",[38646]],[[63923,63923],\\\"mapped\\\",[38728]],[[63924,63924],\\\"mapped\\\",[38936]],[[63925,63925],\\\"mapped\\\",[20363]],[[63926,63926],\\\"mapped\\\",[31150]],[[63927,63927],\\\"mapped\\\",[37300]],[[63928,63928],\\\"mapped\\\",[38584]],[[63929,63929],\\\"mapped\\\",[24801]],[[63930,63930],\\\"mapped\\\",[20102]],[[63931,63931],\\\"mapped\\\",[20698]],[[63932,63932],\\\"mapped\\\",[23534]],[[63933,63933],\\\"mapped\\\",[23615]],[[63934,63934],\\\"mapped\\\",[26009]],[[63935,63935],\\\"mapped\\\",[27138]],[[63936,63936],\\\"mapped\\\",[29134]],[[63937,63937],\\\"mapped\\\",[30274]],[[63938,63938],\\\"mapped\\\",[34044]],[[63939,63939],\\\"mapped\\\",[36988]],[[63940,63940],\\\"mapped\\\",[40845]],[[63941,63941],\\\"mapped\\\",[26248]],[[63942,63942],\\\"mapped\\\",[38446]],[[63943,63943],\\\"mapped\\\",[21129]],[[63944,63944],\\\"mapped\\\",[26491]],[[63945,63945],\\\"mapped\\\",[26611]],[[63946,63946],\\\"mapped\\\",[27969]],[[63947,63947],\\\"mapped\\\",[28316]],[[63948,63948],\\\"mapped\\\",[29705]],[[63949,63949],\\\"mapped\\\",[30041]],[[63950,63950],\\\"mapped\\\",[30827]],[[63951,63951],\\\"mapped\\\",[32016]],[[63952,63952],\\\"mapped\\\",[39006]],[[63953,63953],\\\"mapped\\\",[20845]],[[63954,63954],\\\"mapped\\\",[25134]],[[63955,63955],\\\"mapped\\\",[38520]],[[63956,63956],\\\"mapped\\\",[20523]],[[63957,63957],\\\"mapped\\\",[23833]],[[63958,63958],\\\"mapped\\\",[28138]],[[63959,63959],\\\"mapped\\\",[36650]],[[63960,63960],\\\"mapped\\\",[24459]],[[63961,63961],\\\"mapped\\\",[24900]],[[63962,63962],\\\"mapped\\\",[26647]],[[63963,63963],\\\"mapped\\\",[29575]],[[63964,63964],\\\"mapped\\\",[38534]],[[63965,63965],\\\"mapped\\\",[21033]],[[63966,63966],\\\"mapped\\\",[21519]],[[63967,63967],\\\"mapped\\\",[23653]],[[63968,63968],\\\"mapped\\\",[26131]],[[63969,63969],\\\"mapped\\\",[26446]],[[63970,63970],\\\"mapped\\\",[26792]],[[63971,63971],\\\"mapped\\\",[27877]],[[63972,63972],\\\"mapped\\\",[29702]],[[63973,63973],\\\"mapped\\\",[30178]],[[63974,63974],\\\"mapped\\\",[32633]],[[63975,63975],\\\"mapped\\\",[35023]],[[63976,63976],\\\"mapped\\\",[35041]],[[63977,63977],\\\"mapped\\\",[37324]],[[63978,63978],\\\"mapped\\\",[38626]],[[63979,63979],\\\"mapped\\\",[21311]],[[63980,63980],\\\"mapped\\\",[28346]],[[63981,63981],\\\"mapped\\\",[21533]],[[63982,63982],\\\"mapped\\\",[29136]],[[63983,63983],\\\"mapped\\\",[29848]],[[63984,63984],\\\"mapped\\\",[34298]],[[63985,63985],\\\"mapped\\\",[38563]],[[63986,63986],\\\"mapped\\\",[40023]],[[63987,63987],\\\"mapped\\\",[40607]],[[63988,63988],\\\"mapped\\\",[26519]],[[63989,63989],\\\"mapped\\\",[28107]],[[63990,63990],\\\"mapped\\\",[33256]],[[63991,63991],\\\"mapped\\\",[31435]],[[63992,63992],\\\"mapped\\\",[31520]],[[63993,63993],\\\"mapped\\\",[31890]],[[63994,63994],\\\"mapped\\\",[29376]],[[63995,63995],\\\"mapped\\\",[28825]],[[63996,63996],\\\"mapped\\\",[35672]],[[63997,63997],\\\"mapped\\\",[20160]],[[63998,63998],\\\"mapped\\\",[33590]],[[63999,63999],\\\"mapped\\\",[21050]],[[64000,64000],\\\"mapped\\\",[20999]],[[64001,64001],\\\"mapped\\\",[24230]],[[64002,64002],\\\"mapped\\\",[25299]],[[64003,64003],\\\"mapped\\\",[31958]],[[64004,64004],\\\"mapped\\\",[23429]],[[64005,64005],\\\"mapped\\\",[27934]],[[64006,64006],\\\"mapped\\\",[26292]],[[64007,64007],\\\"mapped\\\",[36667]],[[64008,64008],\\\"mapped\\\",[34892]],[[64009,64009],\\\"mapped\\\",[38477]],[[64010,64010],\\\"mapped\\\",[35211]],[[64011,64011],\\\"mapped\\\",[24275]],[[64012,64012],\\\"mapped\\\",[20800]],[[64013,64013],\\\"mapped\\\",[21952]],[[64014,64015],\\\"valid\\\"],[[64016,64016],\\\"mapped\\\",[22618]],[[64017,64017],\\\"valid\\\"],[[64018,64018],\\\"mapped\\\",[26228]],[[64019,64020],\\\"valid\\\"],[[64021,64021],\\\"mapped\\\",[20958]],[[64022,64022],\\\"mapped\\\",[29482]],[[64023,64023],\\\"mapped\\\",[30410]],[[64024,64024],\\\"mapped\\\",[31036]],[[64025,64025],\\\"mapped\\\",[31070]],[[64026,64026],\\\"mapped\\\",[31077]],[[64027,64027],\\\"mapped\\\",[31119]],[[64028,64028],\\\"mapped\\\",[38742]],[[64029,64029],\\\"mapped\\\",[31934]],[[64030,64030],\\\"mapped\\\",[32701]],[[64031,64031],\\\"valid\\\"],[[64032,64032],\\\"mapped\\\",[34322]],[[64033,64033],\\\"valid\\\"],[[64034,64034],\\\"mapped\\\",[35576]],[[64035,64036],\\\"valid\\\"],[[64037,64037],\\\"mapped\\\",[36920]],[[64038,64038],\\\"mapped\\\",[37117]],[[64039,64041],\\\"valid\\\"],[[64042,64042],\\\"mapped\\\",[39151]],[[64043,64043],\\\"mapped\\\",[39164]],[[64044,64044],\\\"mapped\\\",[39208]],[[64045,64045],\\\"mapped\\\",[40372]],[[64046,64046],\\\"mapped\\\",[37086]],[[64047,64047],\\\"mapped\\\",[38583]],[[64048,64048],\\\"mapped\\\",[20398]],[[64049,64049],\\\"mapped\\\",[20711]],[[64050,64050],\\\"mapped\\\",[20813]],[[64051,64051],\\\"mapped\\\",[21193]],[[64052,64052],\\\"mapped\\\",[21220]],[[64053,64053],\\\"mapped\\\",[21329]],[[64054,64054],\\\"mapped\\\",[21917]],[[64055,64055],\\\"mapped\\\",[22022]],[[64056,64056],\\\"mapped\\\",[22120]],[[64057,64057],\\\"mapped\\\",[22592]],[[64058,64058],\\\"mapped\\\",[22696]],[[64059,64059],\\\"mapped\\\",[23652]],[[64060,64060],\\\"mapped\\\",[23662]],[[64061,64061],\\\"mapped\\\",[24724]],[[64062,64062],\\\"mapped\\\",[24936]],[[64063,64063],\\\"mapped\\\",[24974]],[[64064,64064],\\\"mapped\\\",[25074]],[[64065,64065],\\\"mapped\\\",[25935]],[[64066,64066],\\\"mapped\\\",[26082]],[[64067,64067],\\\"mapped\\\",[26257]],[[64068,64068],\\\"mapped\\\",[26757]],[[64069,64069],\\\"mapped\\\",[28023]],[[64070,64070],\\\"mapped\\\",[28186]],[[64071,64071],\\\"mapped\\\",[28450]],[[64072,64072],\\\"mapped\\\",[29038]],[[64073,64073],\\\"mapped\\\",[29227]],[[64074,64074],\\\"mapped\\\",[29730]],[[64075,64075],\\\"mapped\\\",[30865]],[[64076,64076],\\\"mapped\\\",[31038]],[[64077,64077],\\\"mapped\\\",[31049]],[[64078,64078],\\\"mapped\\\",[31048]],[[64079,64079],\\\"mapped\\\",[31056]],[[64080,64080],\\\"mapped\\\",[31062]],[[64081,64081],\\\"mapped\\\",[31069]],[[64082,64082],\\\"mapped\\\",[31117]],[[64083,64083],\\\"mapped\\\",[31118]],[[64084,64084],\\\"mapped\\\",[31296]],[[64085,64085],\\\"mapped\\\",[31361]],[[64086,64086],\\\"mapped\\\",[31680]],[[64087,64087],\\\"mapped\\\",[32244]],[[64088,64088],\\\"mapped\\\",[32265]],[[64089,64089],\\\"mapped\\\",[32321]],[[64090,64090],\\\"mapped\\\",[32626]],[[64091,64091],\\\"mapped\\\",[32773]],[[64092,64092],\\\"mapped\\\",[33261]],[[64093,64094],\\\"mapped\\\",[33401]],[[64095,64095],\\\"mapped\\\",[33879]],[[64096,64096],\\\"mapped\\\",[35088]],[[64097,64097],\\\"mapped\\\",[35222]],[[64098,64098],\\\"mapped\\\",[35585]],[[64099,64099],\\\"mapped\\\",[35641]],[[64100,64100],\\\"mapped\\\",[36051]],[[64101,64101],\\\"mapped\\\",[36104]],[[64102,64102],\\\"mapped\\\",[36790]],[[64103,64103],\\\"mapped\\\",[36920]],[[64104,64104],\\\"mapped\\\",[38627]],[[64105,64105],\\\"mapped\\\",[38911]],[[64106,64106],\\\"mapped\\\",[38971]],[[64107,64107],\\\"mapped\\\",[24693]],[[64108,64108],\\\"mapped\\\",[148206]],[[64109,64109],\\\"mapped\\\",[33304]],[[64110,64111],\\\"disallowed\\\"],[[64112,64112],\\\"mapped\\\",[20006]],[[64113,64113],\\\"mapped\\\",[20917]],[[64114,64114],\\\"mapped\\\",[20840]],[[64115,64115],\\\"mapped\\\",[20352]],[[64116,64116],\\\"mapped\\\",[20805]],[[64117,64117],\\\"mapped\\\",[20864]],[[64118,64118],\\\"mapped\\\",[21191]],[[64119,64119],\\\"mapped\\\",[21242]],[[64120,64120],\\\"mapped\\\",[21917]],[[64121,64121],\\\"mapped\\\",[21845]],[[64122,64122],\\\"mapped\\\",[21913]],[[64123,64123],\\\"mapped\\\",[21986]],[[64124,64124],\\\"mapped\\\",[22618]],[[64125,64125],\\\"mapped\\\",[22707]],[[64126,64126],\\\"mapped\\\",[22852]],[[64127,64127],\\\"mapped\\\",[22868]],[[64128,64128],\\\"mapped\\\",[23138]],[[64129,64129],\\\"mapped\\\",[23336]],[[64130,64130],\\\"mapped\\\",[24274]],[[64131,64131],\\\"mapped\\\",[24281]],[[64132,64132],\\\"mapped\\\",[24425]],[[64133,64133],\\\"mapped\\\",[24493]],[[64134,64134],\\\"mapped\\\",[24792]],[[64135,64135],\\\"mapped\\\",[24910]],[[64136,64136],\\\"mapped\\\",[24840]],[[64137,64137],\\\"mapped\\\",[24974]],[[64138,64138],\\\"mapped\\\",[24928]],[[64139,64139],\\\"mapped\\\",[25074]],[[64140,64140],\\\"mapped\\\",[25140]],[[64141,64141],\\\"mapped\\\",[25540]],[[64142,64142],\\\"mapped\\\",[25628]],[[64143,64143],\\\"mapped\\\",[25682]],[[64144,64144],\\\"mapped\\\",[25942]],[[64145,64145],\\\"mapped\\\",[26228]],[[64146,64146],\\\"mapped\\\",[26391]],[[64147,64147],\\\"mapped\\\",[26395]],[[64148,64148],\\\"mapped\\\",[26454]],[[64149,64149],\\\"mapped\\\",[27513]],[[64150,64150],\\\"mapped\\\",[27578]],[[64151,64151],\\\"mapped\\\",[27969]],[[64152,64152],\\\"mapped\\\",[28379]],[[64153,64153],\\\"mapped\\\",[28363]],[[64154,64154],\\\"mapped\\\",[28450]],[[64155,64155],\\\"mapped\\\",[28702]],[[64156,64156],\\\"mapped\\\",[29038]],[[64157,64157],\\\"mapped\\\",[30631]],[[64158,64158],\\\"mapped\\\",[29237]],[[64159,64159],\\\"mapped\\\",[29359]],[[64160,64160],\\\"mapped\\\",[29482]],[[64161,64161],\\\"mapped\\\",[29809]],[[64162,64162],\\\"mapped\\\",[29958]],[[64163,64163],\\\"mapped\\\",[30011]],[[64164,64164],\\\"mapped\\\",[30237]],[[64165,64165],\\\"mapped\\\",[30239]],[[64166,64166],\\\"mapped\\\",[30410]],[[64167,64167],\\\"mapped\\\",[30427]],[[64168,64168],\\\"mapped\\\",[30452]],[[64169,64169],\\\"mapped\\\",[30538]],[[64170,64170],\\\"mapped\\\",[30528]],[[64171,64171],\\\"mapped\\\",[30924]],[[64172,64172],\\\"mapped\\\",[31409]],[[64173,64173],\\\"mapped\\\",[31680]],[[64174,64174],\\\"mapped\\\",[31867]],[[64175,64175],\\\"mapped\\\",[32091]],[[64176,64176],\\\"mapped\\\",[32244]],[[64177,64177],\\\"mapped\\\",[32574]],[[64178,64178],\\\"mapped\\\",[32773]],[[64179,64179],\\\"mapped\\\",[33618]],[[64180,64180],\\\"mapped\\\",[33775]],[[64181,64181],\\\"mapped\\\",[34681]],[[64182,64182],\\\"mapped\\\",[35137]],[[64183,64183],\\\"mapped\\\",[35206]],[[64184,64184],\\\"mapped\\\",[35222]],[[64185,64185],\\\"mapped\\\",[35519]],[[64186,64186],\\\"mapped\\\",[35576]],[[64187,64187],\\\"mapped\\\",[35531]],[[64188,64188],\\\"mapped\\\",[35585]],[[64189,64189],\\\"mapped\\\",[35582]],[[64190,64190],\\\"mapped\\\",[35565]],[[64191,64191],\\\"mapped\\\",[35641]],[[64192,64192],\\\"mapped\\\",[35722]],[[64193,64193],\\\"mapped\\\",[36104]],[[64194,64194],\\\"mapped\\\",[36664]],[[64195,64195],\\\"mapped\\\",[36978]],[[64196,64196],\\\"mapped\\\",[37273]],[[64197,64197],\\\"mapped\\\",[37494]],[[64198,64198],\\\"mapped\\\",[38524]],[[64199,64199],\\\"mapped\\\",[38627]],[[64200,64200],\\\"mapped\\\",[38742]],[[64201,64201],\\\"mapped\\\",[38875]],[[64202,64202],\\\"mapped\\\",[38911]],[[64203,64203],\\\"mapped\\\",[38923]],[[64204,64204],\\\"mapped\\\",[38971]],[[64205,64205],\\\"mapped\\\",[39698]],[[64206,64206],\\\"mapped\\\",[40860]],[[64207,64207],\\\"mapped\\\",[141386]],[[64208,64208],\\\"mapped\\\",[141380]],[[64209,64209],\\\"mapped\\\",[144341]],[[64210,64210],\\\"mapped\\\",[15261]],[[64211,64211],\\\"mapped\\\",[16408]],[[64212,64212],\\\"mapped\\\",[16441]],[[64213,64213],\\\"mapped\\\",[152137]],[[64214,64214],\\\"mapped\\\",[154832]],[[64215,64215],\\\"mapped\\\",[163539]],[[64216,64216],\\\"mapped\\\",[40771]],[[64217,64217],\\\"mapped\\\",[40846]],[[64218,64255],\\\"disallowed\\\"],[[64256,64256],\\\"mapped\\\",[102,102]],[[64257,64257],\\\"mapped\\\",[102,105]],[[64258,64258],\\\"mapped\\\",[102,108]],[[64259,64259],\\\"mapped\\\",[102,102,105]],[[64260,64260],\\\"mapped\\\",[102,102,108]],[[64261,64262],\\\"mapped\\\",[115,116]],[[64263,64274],\\\"disallowed\\\"],[[64275,64275],\\\"mapped\\\",[1396,1398]],[[64276,64276],\\\"mapped\\\",[1396,1381]],[[64277,64277],\\\"mapped\\\",[1396,1387]],[[64278,64278],\\\"mapped\\\",[1406,1398]],[[64279,64279],\\\"mapped\\\",[1396,1389]],[[64280,64284],\\\"disallowed\\\"],[[64285,64285],\\\"mapped\\\",[1497,1460]],[[64286,64286],\\\"valid\\\"],[[64287,64287],\\\"mapped\\\",[1522,1463]],[[64288,64288],\\\"mapped\\\",[1506]],[[64289,64289],\\\"mapped\\\",[1488]],[[64290,64290],\\\"mapped\\\",[1491]],[[64291,64291],\\\"mapped\\\",[1492]],[[64292,64292],\\\"mapped\\\",[1499]],[[64293,64293],\\\"mapped\\\",[1500]],[[64294,64294],\\\"mapped\\\",[1501]],[[64295,64295],\\\"mapped\\\",[1512]],[[64296,64296],\\\"mapped\\\",[1514]],[[64297,64297],\\\"disallowed_STD3_mapped\\\",[43]],[[64298,64298],\\\"mapped\\\",[1513,1473]],[[64299,64299],\\\"mapped\\\",[1513,1474]],[[64300,64300],\\\"mapped\\\",[1513,1468,1473]],[[64301,64301],\\\"mapped\\\",[1513,1468,1474]],[[64302,64302],\\\"mapped\\\",[1488,1463]],[[64303,64303],\\\"mapped\\\",[1488,1464]],[[64304,64304],\\\"mapped\\\",[1488,1468]],[[64305,64305],\\\"mapped\\\",[1489,1468]],[[64306,64306],\\\"mapped\\\",[1490,1468]],[[64307,64307],\\\"mapped\\\",[1491,1468]],[[64308,64308],\\\"mapped\\\",[1492,1468]],[[64309,64309],\\\"mapped\\\",[1493,1468]],[[64310,64310],\\\"mapped\\\",[1494,1468]],[[64311,64311],\\\"disallowed\\\"],[[64312,64312],\\\"mapped\\\",[1496,1468]],[[64313,64313],\\\"mapped\\\",[1497,1468]],[[64314,64314],\\\"mapped\\\",[1498,1468]],[[64315,64315],\\\"mapped\\\",[1499,1468]],[[64316,64316],\\\"mapped\\\",[1500,1468]],[[64317,64317],\\\"disallowed\\\"],[[64318,64318],\\\"mapped\\\",[1502,1468]],[[64319,64319],\\\"disallowed\\\"],[[64320,64320],\\\"mapped\\\",[1504,1468]],[[64321,64321],\\\"mapped\\\",[1505,1468]],[[64322,64322],\\\"disallowed\\\"],[[64323,64323],\\\"mapped\\\",[1507,1468]],[[64324,64324],\\\"mapped\\\",[1508,1468]],[[64325,64325],\\\"disallowed\\\"],[[64326,64326],\\\"mapped\\\",[1510,1468]],[[64327,64327],\\\"mapped\\\",[1511,1468]],[[64328,64328],\\\"mapped\\\",[1512,1468]],[[64329,64329],\\\"mapped\\\",[1513,1468]],[[64330,64330],\\\"mapped\\\",[1514,1468]],[[64331,64331],\\\"mapped\\\",[1493,1465]],[[64332,64332],\\\"mapped\\\",[1489,1471]],[[64333,64333],\\\"mapped\\\",[1499,1471]],[[64334,64334],\\\"mapped\\\",[1508,1471]],[[64335,64335],\\\"mapped\\\",[1488,1500]],[[64336,64337],\\\"mapped\\\",[1649]],[[64338,64341],\\\"mapped\\\",[1659]],[[64342,64345],\\\"mapped\\\",[1662]],[[64346,64349],\\\"mapped\\\",[1664]],[[64350,64353],\\\"mapped\\\",[1658]],[[64354,64357],\\\"mapped\\\",[1663]],[[64358,64361],\\\"mapped\\\",[1657]],[[64362,64365],\\\"mapped\\\",[1700]],[[64366,64369],\\\"mapped\\\",[1702]],[[64370,64373],\\\"mapped\\\",[1668]],[[64374,64377],\\\"mapped\\\",[1667]],[[64378,64381],\\\"mapped\\\",[1670]],[[64382,64385],\\\"mapped\\\",[1671]],[[64386,64387],\\\"mapped\\\",[1677]],[[64388,64389],\\\"mapped\\\",[1676]],[[64390,64391],\\\"mapped\\\",[1678]],[[64392,64393],\\\"mapped\\\",[1672]],[[64394,64395],\\\"mapped\\\",[1688]],[[64396,64397],\\\"mapped\\\",[1681]],[[64398,64401],\\\"mapped\\\",[1705]],[[64402,64405],\\\"mapped\\\",[1711]],[[64406,64409],\\\"mapped\\\",[1715]],[[64410,64413],\\\"mapped\\\",[1713]],[[64414,64415],\\\"mapped\\\",[1722]],[[64416,64419],\\\"mapped\\\",[1723]],[[64420,64421],\\\"mapped\\\",[1728]],[[64422,64425],\\\"mapped\\\",[1729]],[[64426,64429],\\\"mapped\\\",[1726]],[[64430,64431],\\\"mapped\\\",[1746]],[[64432,64433],\\\"mapped\\\",[1747]],[[64434,64449],\\\"valid\\\",[],\\\"NV8\\\"],[[64450,64466],\\\"disallowed\\\"],[[64467,64470],\\\"mapped\\\",[1709]],[[64471,64472],\\\"mapped\\\",[1735]],[[64473,64474],\\\"mapped\\\",[1734]],[[64475,64476],\\\"mapped\\\",[1736]],[[64477,64477],\\\"mapped\\\",[1735,1652]],[[64478,64479],\\\"mapped\\\",[1739]],[[64480,64481],\\\"mapped\\\",[1733]],[[64482,64483],\\\"mapped\\\",[1737]],[[64484,64487],\\\"mapped\\\",[1744]],[[64488,64489],\\\"mapped\\\",[1609]],[[64490,64491],\\\"mapped\\\",[1574,1575]],[[64492,64493],\\\"mapped\\\",[1574,1749]],[[64494,64495],\\\"mapped\\\",[1574,1608]],[[64496,64497],\\\"mapped\\\",[1574,1735]],[[64498,64499],\\\"mapped\\\",[1574,1734]],[[64500,64501],\\\"mapped\\\",[1574,1736]],[[64502,64504],\\\"mapped\\\",[1574,1744]],[[64505,64507],\\\"mapped\\\",[1574,1609]],[[64508,64511],\\\"mapped\\\",[1740]],[[64512,64512],\\\"mapped\\\",[1574,1580]],[[64513,64513],\\\"mapped\\\",[1574,1581]],[[64514,64514],\\\"mapped\\\",[1574,1605]],[[64515,64515],\\\"mapped\\\",[1574,1609]],[[64516,64516],\\\"mapped\\\",[1574,1610]],[[64517,64517],\\\"mapped\\\",[1576,1580]],[[64518,64518],\\\"mapped\\\",[1576,1581]],[[64519,64519],\\\"mapped\\\",[1576,1582]],[[64520,64520],\\\"mapped\\\",[1576,1605]],[[64521,64521],\\\"mapped\\\",[1576,1609]],[[64522,64522],\\\"mapped\\\",[1576,1610]],[[64523,64523],\\\"mapped\\\",[1578,1580]],[[64524,64524],\\\"mapped\\\",[1578,1581]],[[64525,64525],\\\"mapped\\\",[1578,1582]],[[64526,64526],\\\"mapped\\\",[1578,1605]],[[64527,64527],\\\"mapped\\\",[1578,1609]],[[64528,64528],\\\"mapped\\\",[1578,1610]],[[64529,64529],\\\"mapped\\\",[1579,1580]],[[64530,64530],\\\"mapped\\\",[1579,1605]],[[64531,64531],\\\"mapped\\\",[1579,1609]],[[64532,64532],\\\"mapped\\\",[1579,1610]],[[64533,64533],\\\"mapped\\\",[1580,1581]],[[64534,64534],\\\"mapped\\\",[1580,1605]],[[64535,64535],\\\"mapped\\\",[1581,1580]],[[64536,64536],\\\"mapped\\\",[1581,1605]],[[64537,64537],\\\"mapped\\\",[1582,1580]],[[64538,64538],\\\"mapped\\\",[1582,1581]],[[64539,64539],\\\"mapped\\\",[1582,1605]],[[64540,64540],\\\"mapped\\\",[1587,1580]],[[64541,64541],\\\"mapped\\\",[1587,1581]],[[64542,64542],\\\"mapped\\\",[1587,1582]],[[64543,64543],\\\"mapped\\\",[1587,1605]],[[64544,64544],\\\"mapped\\\",[1589,1581]],[[64545,64545],\\\"mapped\\\",[1589,1605]],[[64546,64546],\\\"mapped\\\",[1590,1580]],[[64547,64547],\\\"mapped\\\",[1590,1581]],[[64548,64548],\\\"mapped\\\",[1590,1582]],[[64549,64549],\\\"mapped\\\",[1590,1605]],[[64550,64550],\\\"mapped\\\",[1591,1581]],[[64551,64551],\\\"mapped\\\",[1591,1605]],[[64552,64552],\\\"mapped\\\",[1592,1605]],[[64553,64553],\\\"mapped\\\",[1593,1580]],[[64554,64554],\\\"mapped\\\",[1593,1605]],[[64555,64555],\\\"mapped\\\",[1594,1580]],[[64556,64556],\\\"mapped\\\",[1594,1605]],[[64557,64557],\\\"mapped\\\",[1601,1580]],[[64558,64558],\\\"mapped\\\",[1601,1581]],[[64559,64559],\\\"mapped\\\",[1601,1582]],[[64560,64560],\\\"mapped\\\",[1601,1605]],[[64561,64561],\\\"mapped\\\",[1601,1609]],[[64562,64562],\\\"mapped\\\",[1601,1610]],[[64563,64563],\\\"mapped\\\",[1602,1581]],[[64564,64564],\\\"mapped\\\",[1602,1605]],[[64565,64565],\\\"mapped\\\",[1602,1609]],[[64566,64566],\\\"mapped\\\",[1602,1610]],[[64567,64567],\\\"mapped\\\",[1603,1575]],[[64568,64568],\\\"mapped\\\",[1603,1580]],[[64569,64569],\\\"mapped\\\",[1603,1581]],[[64570,64570],\\\"mapped\\\",[1603,1582]],[[64571,64571],\\\"mapped\\\",[1603,1604]],[[64572,64572],\\\"mapped\\\",[1603,1605]],[[64573,64573],\\\"mapped\\\",[1603,1609]],[[64574,64574],\\\"mapped\\\",[1603,1610]],[[64575,64575],\\\"mapped\\\",[1604,1580]],[[64576,64576],\\\"mapped\\\",[1604,1581]],[[64577,64577],\\\"mapped\\\",[1604,1582]],[[64578,64578],\\\"mapped\\\",[1604,1605]],[[64579,64579],\\\"mapped\\\",[1604,1609]],[[64580,64580],\\\"mapped\\\",[1604,1610]],[[64581,64581],\\\"mapped\\\",[1605,1580]],[[64582,64582],\\\"mapped\\\",[1605,1581]],[[64583,64583],\\\"mapped\\\",[1605,1582]],[[64584,64584],\\\"mapped\\\",[1605,1605]],[[64585,64585],\\\"mapped\\\",[1605,1609]],[[64586,64586],\\\"mapped\\\",[1605,1610]],[[64587,64587],\\\"mapped\\\",[1606,1580]],[[64588,64588],\\\"mapped\\\",[1606,1581]],[[64589,64589],\\\"mapped\\\",[1606,1582]],[[64590,64590],\\\"mapped\\\",[1606,1605]],[[64591,64591],\\\"mapped\\\",[1606,1609]],[[64592,64592],\\\"mapped\\\",[1606,1610]],[[64593,64593],\\\"mapped\\\",[1607,1580]],[[64594,64594],\\\"mapped\\\",[1607,1605]],[[64595,64595],\\\"mapped\\\",[1607,1609]],[[64596,64596],\\\"mapped\\\",[1607,1610]],[[64597,64597],\\\"mapped\\\",[1610,1580]],[[64598,64598],\\\"mapped\\\",[1610,1581]],[[64599,64599],\\\"mapped\\\",[1610,1582]],[[64600,64600],\\\"mapped\\\",[1610,1605]],[[64601,64601],\\\"mapped\\\",[1610,1609]],[[64602,64602],\\\"mapped\\\",[1610,1610]],[[64603,64603],\\\"mapped\\\",[1584,1648]],[[64604,64604],\\\"mapped\\\",[1585,1648]],[[64605,64605],\\\"mapped\\\",[1609,1648]],[[64606,64606],\\\"disallowed_STD3_mapped\\\",[32,1612,1617]],[[64607,64607],\\\"disallowed_STD3_mapped\\\",[32,1613,1617]],[[64608,64608],\\\"disallowed_STD3_mapped\\\",[32,1614,1617]],[[64609,64609],\\\"disallowed_STD3_mapped\\\",[32,1615,1617]],[[64610,64610],\\\"disallowed_STD3_mapped\\\",[32,1616,1617]],[[64611,64611],\\\"disallowed_STD3_mapped\\\",[32,1617,1648]],[[64612,64612],\\\"mapped\\\",[1574,1585]],[[64613,64613],\\\"mapped\\\",[1574,1586]],[[64614,64614],\\\"mapped\\\",[1574,1605]],[[64615,64615],\\\"mapped\\\",[1574,1606]],[[64616,64616],\\\"mapped\\\",[1574,1609]],[[64617,64617],\\\"mapped\\\",[1574,1610]],[[64618,64618],\\\"mapped\\\",[1576,1585]],[[64619,64619],\\\"mapped\\\",[1576,1586]],[[64620,64620],\\\"mapped\\\",[1576,1605]],[[64621,64621],\\\"mapped\\\",[1576,1606]],[[64622,64622],\\\"mapped\\\",[1576,1609]],[[64623,64623],\\\"mapped\\\",[1576,1610]],[[64624,64624],\\\"mapped\\\",[1578,1585]],[[64625,64625],\\\"mapped\\\",[1578,1586]],[[64626,64626],\\\"mapped\\\",[1578,1605]],[[64627,64627],\\\"mapped\\\",[1578,1606]],[[64628,64628],\\\"mapped\\\",[1578,1609]],[[64629,64629],\\\"mapped\\\",[1578,1610]],[[64630,64630],\\\"mapped\\\",[1579,1585]],[[64631,64631],\\\"mapped\\\",[1579,1586]],[[64632,64632],\\\"mapped\\\",[1579,1605]],[[64633,64633],\\\"mapped\\\",[1579,1606]],[[64634,64634],\\\"mapped\\\",[1579,1609]],[[64635,64635],\\\"mapped\\\",[1579,1610]],[[64636,64636],\\\"mapped\\\",[1601,1609]],[[64637,64637],\\\"mapped\\\",[1601,1610]],[[64638,64638],\\\"mapped\\\",[1602,1609]],[[64639,64639],\\\"mapped\\\",[1602,1610]],[[64640,64640],\\\"mapped\\\",[1603,1575]],[[64641,64641],\\\"mapped\\\",[1603,1604]],[[64642,64642],\\\"mapped\\\",[1603,1605]],[[64643,64643],\\\"mapped\\\",[1603,1609]],[[64644,64644],\\\"mapped\\\",[1603,1610]],[[64645,64645],\\\"mapped\\\",[1604,1605]],[[64646,64646],\\\"mapped\\\",[1604,1609]],[[64647,64647],\\\"mapped\\\",[1604,1610]],[[64648,64648],\\\"mapped\\\",[1605,1575]],[[64649,64649],\\\"mapped\\\",[1605,1605]],[[64650,64650],\\\"mapped\\\",[1606,1585]],[[64651,64651],\\\"mapped\\\",[1606,1586]],[[64652,64652],\\\"mapped\\\",[1606,1605]],[[64653,64653],\\\"mapped\\\",[1606,1606]],[[64654,64654],\\\"mapped\\\",[1606,1609]],[[64655,64655],\\\"mapped\\\",[1606,1610]],[[64656,64656],\\\"mapped\\\",[1609,1648]],[[64657,64657],\\\"mapped\\\",[1610,1585]],[[64658,64658],\\\"mapped\\\",[1610,1586]],[[64659,64659],\\\"mapped\\\",[1610,1605]],[[64660,64660],\\\"mapped\\\",[1610,1606]],[[64661,64661],\\\"mapped\\\",[1610,1609]],[[64662,64662],\\\"mapped\\\",[1610,1610]],[[64663,64663],\\\"mapped\\\",[1574,1580]],[[64664,64664],\\\"mapped\\\",[1574,1581]],[[64665,64665],\\\"mapped\\\",[1574,1582]],[[64666,64666],\\\"mapped\\\",[1574,1605]],[[64667,64667],\\\"mapped\\\",[1574,1607]],[[64668,64668],\\\"mapped\\\",[1576,1580]],[[64669,64669],\\\"mapped\\\",[1576,1581]],[[64670,64670],\\\"mapped\\\",[1576,1582]],[[64671,64671],\\\"mapped\\\",[1576,1605]],[[64672,64672],\\\"mapped\\\",[1576,1607]],[[64673,64673],\\\"mapped\\\",[1578,1580]],[[64674,64674],\\\"mapped\\\",[1578,1581]],[[64675,64675],\\\"mapped\\\",[1578,1582]],[[64676,64676],\\\"mapped\\\",[1578,1605]],[[64677,64677],\\\"mapped\\\",[1578,1607]],[[64678,64678],\\\"mapped\\\",[1579,1605]],[[64679,64679],\\\"mapped\\\",[1580,1581]],[[64680,64680],\\\"mapped\\\",[1580,1605]],[[64681,64681],\\\"mapped\\\",[1581,1580]],[[64682,64682],\\\"mapped\\\",[1581,1605]],[[64683,64683],\\\"mapped\\\",[1582,1580]],[[64684,64684],\\\"mapped\\\",[1582,1605]],[[64685,64685],\\\"mapped\\\",[1587,1580]],[[64686,64686],\\\"mapped\\\",[1587,1581]],[[64687,64687],\\\"mapped\\\",[1587,1582]],[[64688,64688],\\\"mapped\\\",[1587,1605]],[[64689,64689],\\\"mapped\\\",[1589,1581]],[[64690,64690],\\\"mapped\\\",[1589,1582]],[[64691,64691],\\\"mapped\\\",[1589,1605]],[[64692,64692],\\\"mapped\\\",[1590,1580]],[[64693,64693],\\\"mapped\\\",[1590,1581]],[[64694,64694],\\\"mapped\\\",[1590,1582]],[[64695,64695],\\\"mapped\\\",[1590,1605]],[[64696,64696],\\\"mapped\\\",[1591,1581]],[[64697,64697],\\\"mapped\\\",[1592,1605]],[[64698,64698],\\\"mapped\\\",[1593,1580]],[[64699,64699],\\\"mapped\\\",[1593,1605]],[[64700,64700],\\\"mapped\\\",[1594,1580]],[[64701,64701],\\\"mapped\\\",[1594,1605]],[[64702,64702],\\\"mapped\\\",[1601,1580]],[[64703,64703],\\\"mapped\\\",[1601,1581]],[[64704,64704],\\\"mapped\\\",[1601,1582]],[[64705,64705],\\\"mapped\\\",[1601,1605]],[[64706,64706],\\\"mapped\\\",[1602,1581]],[[64707,64707],\\\"mapped\\\",[1602,1605]],[[64708,64708],\\\"mapped\\\",[1603,1580]],[[64709,64709],\\\"mapped\\\",[1603,1581]],[[64710,64710],\\\"mapped\\\",[1603,1582]],[[64711,64711],\\\"mapped\\\",[1603,1604]],[[64712,64712],\\\"mapped\\\",[1603,1605]],[[64713,64713],\\\"mapped\\\",[1604,1580]],[[64714,64714],\\\"mapped\\\",[1604,1581]],[[64715,64715],\\\"mapped\\\",[1604,1582]],[[64716,64716],\\\"mapped\\\",[1604,1605]],[[64717,64717],\\\"mapped\\\",[1604,1607]],[[64718,64718],\\\"mapped\\\",[1605,1580]],[[64719,64719],\\\"mapped\\\",[1605,1581]],[[64720,64720],\\\"mapped\\\",[1605,1582]],[[64721,64721],\\\"mapped\\\",[1605,1605]],[[64722,64722],\\\"mapped\\\",[1606,1580]],[[64723,64723],\\\"mapped\\\",[1606,1581]],[[64724,64724],\\\"mapped\\\",[1606,1582]],[[64725,64725],\\\"mapped\\\",[1606,1605]],[[64726,64726],\\\"mapped\\\",[1606,1607]],[[64727,64727],\\\"mapped\\\",[1607,1580]],[[64728,64728],\\\"mapped\\\",[1607,1605]],[[64729,64729],\\\"mapped\\\",[1607,1648]],[[64730,64730],\\\"mapped\\\",[1610,1580]],[[64731,64731],\\\"mapped\\\",[1610,1581]],[[64732,64732],\\\"mapped\\\",[1610,1582]],[[64733,64733],\\\"mapped\\\",[1610,1605]],[[64734,64734],\\\"mapped\\\",[1610,1607]],[[64735,64735],\\\"mapped\\\",[1574,1605]],[[64736,64736],\\\"mapped\\\",[1574,1607]],[[64737,64737],\\\"mapped\\\",[1576,1605]],[[64738,64738],\\\"mapped\\\",[1576,1607]],[[64739,64739],\\\"mapped\\\",[1578,1605]],[[64740,64740],\\\"mapped\\\",[1578,1607]],[[64741,64741],\\\"mapped\\\",[1579,1605]],[[64742,64742],\\\"mapped\\\",[1579,1607]],[[64743,64743],\\\"mapped\\\",[1587,1605]],[[64744,64744],\\\"mapped\\\",[1587,1607]],[[64745,64745],\\\"mapped\\\",[1588,1605]],[[64746,64746],\\\"mapped\\\",[1588,1607]],[[64747,64747],\\\"mapped\\\",[1603,1604]],[[64748,64748],\\\"mapped\\\",[1603,1605]],[[64749,64749],\\\"mapped\\\",[1604,1605]],[[64750,64750],\\\"mapped\\\",[1606,1605]],[[64751,64751],\\\"mapped\\\",[1606,1607]],[[64752,64752],\\\"mapped\\\",[1610,1605]],[[64753,64753],\\\"mapped\\\",[1610,1607]],[[64754,64754],\\\"mapped\\\",[1600,1614,1617]],[[64755,64755],\\\"mapped\\\",[1600,1615,1617]],[[64756,64756],\\\"mapped\\\",[1600,1616,1617]],[[64757,64757],\\\"mapped\\\",[1591,1609]],[[64758,64758],\\\"mapped\\\",[1591,1610]],[[64759,64759],\\\"mapped\\\",[1593,1609]],[[64760,64760],\\\"mapped\\\",[1593,1610]],[[64761,64761],\\\"mapped\\\",[1594,1609]],[[64762,64762],\\\"mapped\\\",[1594,1610]],[[64763,64763],\\\"mapped\\\",[1587,1609]],[[64764,64764],\\\"mapped\\\",[1587,1610]],[[64765,64765],\\\"mapped\\\",[1588,1609]],[[64766,64766],\\\"mapped\\\",[1588,1610]],[[64767,64767],\\\"mapped\\\",[1581,1609]],[[64768,64768],\\\"mapped\\\",[1581,1610]],[[64769,64769],\\\"mapped\\\",[1580,1609]],[[64770,64770],\\\"mapped\\\",[1580,1610]],[[64771,64771],\\\"mapped\\\",[1582,1609]],[[64772,64772],\\\"mapped\\\",[1582,1610]],[[64773,64773],\\\"mapped\\\",[1589,1609]],[[64774,64774],\\\"mapped\\\",[1589,1610]],[[64775,64775],\\\"mapped\\\",[1590,1609]],[[64776,64776],\\\"mapped\\\",[1590,1610]],[[64777,64777],\\\"mapped\\\",[1588,1580]],[[64778,64778],\\\"mapped\\\",[1588,1581]],[[64779,64779],\\\"mapped\\\",[1588,1582]],[[64780,64780],\\\"mapped\\\",[1588,1605]],[[64781,64781],\\\"mapped\\\",[1588,1585]],[[64782,64782],\\\"mapped\\\",[1587,1585]],[[64783,64783],\\\"mapped\\\",[1589,1585]],[[64784,64784],\\\"mapped\\\",[1590,1585]],[[64785,64785],\\\"mapped\\\",[1591,1609]],[[64786,64786],\\\"mapped\\\",[1591,1610]],[[64787,64787],\\\"mapped\\\",[1593,1609]],[[64788,64788],\\\"mapped\\\",[1593,1610]],[[64789,64789],\\\"mapped\\\",[1594,1609]],[[64790,64790],\\\"mapped\\\",[1594,1610]],[[64791,64791],\\\"mapped\\\",[1587,1609]],[[64792,64792],\\\"mapped\\\",[1587,1610]],[[64793,64793],\\\"mapped\\\",[1588,1609]],[[64794,64794],\\\"mapped\\\",[1588,1610]],[[64795,64795],\\\"mapped\\\",[1581,1609]],[[64796,64796],\\\"mapped\\\",[1581,1610]],[[64797,64797],\\\"mapped\\\",[1580,1609]],[[64798,64798],\\\"mapped\\\",[1580,1610]],[[64799,64799],\\\"mapped\\\",[1582,1609]],[[64800,64800],\\\"mapped\\\",[1582,1610]],[[64801,64801],\\\"mapped\\\",[1589,1609]],[[64802,64802],\\\"mapped\\\",[1589,1610]],[[64803,64803],\\\"mapped\\\",[1590,1609]],[[64804,64804],\\\"mapped\\\",[1590,1610]],[[64805,64805],\\\"mapped\\\",[1588,1580]],[[64806,64806],\\\"mapped\\\",[1588,1581]],[[64807,64807],\\\"mapped\\\",[1588,1582]],[[64808,64808],\\\"mapped\\\",[1588,1605]],[[64809,64809],\\\"mapped\\\",[1588,1585]],[[64810,64810],\\\"mapped\\\",[1587,1585]],[[64811,64811],\\\"mapped\\\",[1589,1585]],[[64812,64812],\\\"mapped\\\",[1590,1585]],[[64813,64813],\\\"mapped\\\",[1588,1580]],[[64814,64814],\\\"mapped\\\",[1588,1581]],[[64815,64815],\\\"mapped\\\",[1588,1582]],[[64816,64816],\\\"mapped\\\",[1588,1605]],[[64817,64817],\\\"mapped\\\",[1587,1607]],[[64818,64818],\\\"mapped\\\",[1588,1607]],[[64819,64819],\\\"mapped\\\",[1591,1605]],[[64820,64820],\\\"mapped\\\",[1587,1580]],[[64821,64821],\\\"mapped\\\",[1587,1581]],[[64822,64822],\\\"mapped\\\",[1587,1582]],[[64823,64823],\\\"mapped\\\",[1588,1580]],[[64824,64824],\\\"mapped\\\",[1588,1581]],[[64825,64825],\\\"mapped\\\",[1588,1582]],[[64826,64826],\\\"mapped\\\",[1591,1605]],[[64827,64827],\\\"mapped\\\",[1592,1605]],[[64828,64829],\\\"mapped\\\",[1575,1611]],[[64830,64831],\\\"valid\\\",[],\\\"NV8\\\"],[[64832,64847],\\\"disallowed\\\"],[[64848,64848],\\\"mapped\\\",[1578,1580,1605]],[[64849,64850],\\\"mapped\\\",[1578,1581,1580]],[[64851,64851],\\\"mapped\\\",[1578,1581,1605]],[[64852,64852],\\\"mapped\\\",[1578,1582,1605]],[[64853,64853],\\\"mapped\\\",[1578,1605,1580]],[[64854,64854],\\\"mapped\\\",[1578,1605,1581]],[[64855,64855],\\\"mapped\\\",[1578,1605,1582]],[[64856,64857],\\\"mapped\\\",[1580,1605,1581]],[[64858,64858],\\\"mapped\\\",[1581,1605,1610]],[[64859,64859],\\\"mapped\\\",[1581,1605,1609]],[[64860,64860],\\\"mapped\\\",[1587,1581,1580]],[[64861,64861],\\\"mapped\\\",[1587,1580,1581]],[[64862,64862],\\\"mapped\\\",[1587,1580,1609]],[[64863,64864],\\\"mapped\\\",[1587,1605,1581]],[[64865,64865],\\\"mapped\\\",[1587,1605,1580]],[[64866,64867],\\\"mapped\\\",[1587,1605,1605]],[[64868,64869],\\\"mapped\\\",[1589,1581,1581]],[[64870,64870],\\\"mapped\\\",[1589,1605,1605]],[[64871,64872],\\\"mapped\\\",[1588,1581,1605]],[[64873,64873],\\\"mapped\\\",[1588,1580,1610]],[[64874,64875],\\\"mapped\\\",[1588,1605,1582]],[[64876,64877],\\\"mapped\\\",[1588,1605,1605]],[[64878,64878],\\\"mapped\\\",[1590,1581,1609]],[[64879,64880],\\\"mapped\\\",[1590,1582,1605]],[[64881,64882],\\\"mapped\\\",[1591,1605,1581]],[[64883,64883],\\\"mapped\\\",[1591,1605,1605]],[[64884,64884],\\\"mapped\\\",[1591,1605,1610]],[[64885,64885],\\\"mapped\\\",[1593,1580,1605]],[[64886,64887],\\\"mapped\\\",[1593,1605,1605]],[[64888,64888],\\\"mapped\\\",[1593,1605,1609]],[[64889,64889],\\\"mapped\\\",[1594,1605,1605]],[[64890,64890],\\\"mapped\\\",[1594,1605,1610]],[[64891,64891],\\\"mapped\\\",[1594,1605,1609]],[[64892,64893],\\\"mapped\\\",[1601,1582,1605]],[[64894,64894],\\\"mapped\\\",[1602,1605,1581]],[[64895,64895],\\\"mapped\\\",[1602,1605,1605]],[[64896,64896],\\\"mapped\\\",[1604,1581,1605]],[[64897,64897],\\\"mapped\\\",[1604,1581,1610]],[[64898,64898],\\\"mapped\\\",[1604,1581,1609]],[[64899,64900],\\\"mapped\\\",[1604,1580,1580]],[[64901,64902],\\\"mapped\\\",[1604,1582,1605]],[[64903,64904],\\\"mapped\\\",[1604,1605,1581]],[[64905,64905],\\\"mapped\\\",[1605,1581,1580]],[[64906,64906],\\\"mapped\\\",[1605,1581,1605]],[[64907,64907],\\\"mapped\\\",[1605,1581,1610]],[[64908,64908],\\\"mapped\\\",[1605,1580,1581]],[[64909,64909],\\\"mapped\\\",[1605,1580,1605]],[[64910,64910],\\\"mapped\\\",[1605,1582,1580]],[[64911,64911],\\\"mapped\\\",[1605,1582,1605]],[[64912,64913],\\\"disallowed\\\"],[[64914,64914],\\\"mapped\\\",[1605,1580,1582]],[[64915,64915],\\\"mapped\\\",[1607,1605,1580]],[[64916,64916],\\\"mapped\\\",[1607,1605,1605]],[[64917,64917],\\\"mapped\\\",[1606,1581,1605]],[[64918,64918],\\\"mapped\\\",[1606,1581,1609]],[[64919,64920],\\\"mapped\\\",[1606,1580,1605]],[[64921,64921],\\\"mapped\\\",[1606,1580,1609]],[[64922,64922],\\\"mapped\\\",[1606,1605,1610]],[[64923,64923],\\\"mapped\\\",[1606,1605,1609]],[[64924,64925],\\\"mapped\\\",[1610,1605,1605]],[[64926,64926],\\\"mapped\\\",[1576,1582,1610]],[[64927,64927],\\\"mapped\\\",[1578,1580,1610]],[[64928,64928],\\\"mapped\\\",[1578,1580,1609]],[[64929,64929],\\\"mapped\\\",[1578,1582,1610]],[[64930,64930],\\\"mapped\\\",[1578,1582,1609]],[[64931,64931],\\\"mapped\\\",[1578,1605,1610]],[[64932,64932],\\\"mapped\\\",[1578,1605,1609]],[[64933,64933],\\\"mapped\\\",[1580,1605,1610]],[[64934,64934],\\\"mapped\\\",[1580,1581,1609]],[[64935,64935],\\\"mapped\\\",[1580,1605,1609]],[[64936,64936],\\\"mapped\\\",[1587,1582,1609]],[[64937,64937],\\\"mapped\\\",[1589,1581,1610]],[[64938,64938],\\\"mapped\\\",[1588,1581,1610]],[[64939,64939],\\\"mapped\\\",[1590,1581,1610]],[[64940,64940],\\\"mapped\\\",[1604,1580,1610]],[[64941,64941],\\\"mapped\\\",[1604,1605,1610]],[[64942,64942],\\\"mapped\\\",[1610,1581,1610]],[[64943,64943],\\\"mapped\\\",[1610,1580,1610]],[[64944,64944],\\\"mapped\\\",[1610,1605,1610]],[[64945,64945],\\\"mapped\\\",[1605,1605,1610]],[[64946,64946],\\\"mapped\\\",[1602,1605,1610]],[[64947,64947],\\\"mapped\\\",[1606,1581,1610]],[[64948,64948],\\\"mapped\\\",[1602,1605,1581]],[[64949,64949],\\\"mapped\\\",[1604,1581,1605]],[[64950,64950],\\\"mapped\\\",[1593,1605,1610]],[[64951,64951],\\\"mapped\\\",[1603,1605,1610]],[[64952,64952],\\\"mapped\\\",[1606,1580,1581]],[[64953,64953],\\\"mapped\\\",[1605,1582,1610]],[[64954,64954],\\\"mapped\\\",[1604,1580,1605]],[[64955,64955],\\\"mapped\\\",[1603,1605,1605]],[[64956,64956],\\\"mapped\\\",[1604,1580,1605]],[[64957,64957],\\\"mapped\\\",[1606,1580,1581]],[[64958,64958],\\\"mapped\\\",[1580,1581,1610]],[[64959,64959],\\\"mapped\\\",[1581,1580,1610]],[[64960,64960],\\\"mapped\\\",[1605,1580,1610]],[[64961,64961],\\\"mapped\\\",[1601,1605,1610]],[[64962,64962],\\\"mapped\\\",[1576,1581,1610]],[[64963,64963],\\\"mapped\\\",[1603,1605,1605]],[[64964,64964],\\\"mapped\\\",[1593,1580,1605]],[[64965,64965],\\\"mapped\\\",[1589,1605,1605]],[[64966,64966],\\\"mapped\\\",[1587,1582,1610]],[[64967,64967],\\\"mapped\\\",[1606,1580,1610]],[[64968,64975],\\\"disallowed\\\"],[[64976,65007],\\\"disallowed\\\"],[[65008,65008],\\\"mapped\\\",[1589,1604,1746]],[[65009,65009],\\\"mapped\\\",[1602,1604,1746]],[[65010,65010],\\\"mapped\\\",[1575,1604,1604,1607]],[[65011,65011],\\\"mapped\\\",[1575,1603,1576,1585]],[[65012,65012],\\\"mapped\\\",[1605,1581,1605,1583]],[[65013,65013],\\\"mapped\\\",[1589,1604,1593,1605]],[[65014,65014],\\\"mapped\\\",[1585,1587,1608,1604]],[[65015,65015],\\\"mapped\\\",[1593,1604,1610,1607]],[[65016,65016],\\\"mapped\\\",[1608,1587,1604,1605]],[[65017,65017],\\\"mapped\\\",[1589,1604,1609]],[[65018,65018],\\\"disallowed_STD3_mapped\\\",[1589,1604,1609,32,1575,1604,1604,1607,32,1593,1604,1610,1607,32,1608,1587,1604,1605]],[[65019,65019],\\\"disallowed_STD3_mapped\\\",[1580,1604,32,1580,1604,1575,1604,1607]],[[65020,65020],\\\"mapped\\\",[1585,1740,1575,1604]],[[65021,65021],\\\"valid\\\",[],\\\"NV8\\\"],[[65022,65023],\\\"disallowed\\\"],[[65024,65039],\\\"ignored\\\"],[[65040,65040],\\\"disallowed_STD3_mapped\\\",[44]],[[65041,65041],\\\"mapped\\\",[12289]],[[65042,65042],\\\"disallowed\\\"],[[65043,65043],\\\"disallowed_STD3_mapped\\\",[58]],[[65044,65044],\\\"disallowed_STD3_mapped\\\",[59]],[[65045,65045],\\\"disallowed_STD3_mapped\\\",[33]],[[65046,65046],\\\"disallowed_STD3_mapped\\\",[63]],[[65047,65047],\\\"mapped\\\",[12310]],[[65048,65048],\\\"mapped\\\",[12311]],[[65049,65049],\\\"disallowed\\\"],[[65050,65055],\\\"disallowed\\\"],[[65056,65059],\\\"valid\\\"],[[65060,65062],\\\"valid\\\"],[[65063,65069],\\\"valid\\\"],[[65070,65071],\\\"valid\\\"],[[65072,65072],\\\"disallowed\\\"],[[65073,65073],\\\"mapped\\\",[8212]],[[65074,65074],\\\"mapped\\\",[8211]],[[65075,65076],\\\"disallowed_STD3_mapped\\\",[95]],[[65077,65077],\\\"disallowed_STD3_mapped\\\",[40]],[[65078,65078],\\\"disallowed_STD3_mapped\\\",[41]],[[65079,65079],\\\"disallowed_STD3_mapped\\\",[123]],[[65080,65080],\\\"disallowed_STD3_mapped\\\",[125]],[[65081,65081],\\\"mapped\\\",[12308]],[[65082,65082],\\\"mapped\\\",[12309]],[[65083,65083],\\\"mapped\\\",[12304]],[[65084,65084],\\\"mapped\\\",[12305]],[[65085,65085],\\\"mapped\\\",[12298]],[[65086,65086],\\\"mapped\\\",[12299]],[[65087,65087],\\\"mapped\\\",[12296]],[[65088,65088],\\\"mapped\\\",[12297]],[[65089,65089],\\\"mapped\\\",[12300]],[[65090,65090],\\\"mapped\\\",[12301]],[[65091,65091],\\\"mapped\\\",[12302]],[[65092,65092],\\\"mapped\\\",[12303]],[[65093,65094],\\\"valid\\\",[],\\\"NV8\\\"],[[65095,65095],\\\"disallowed_STD3_mapped\\\",[91]],[[65096,65096],\\\"disallowed_STD3_mapped\\\",[93]],[[65097,65100],\\\"disallowed_STD3_mapped\\\",[32,773]],[[65101,65103],\\\"disallowed_STD3_mapped\\\",[95]],[[65104,65104],\\\"disallowed_STD3_mapped\\\",[44]],[[65105,65105],\\\"mapped\\\",[12289]],[[65106,65106],\\\"disallowed\\\"],[[65107,65107],\\\"disallowed\\\"],[[65108,65108],\\\"disallowed_STD3_mapped\\\",[59]],[[65109,65109],\\\"disallowed_STD3_mapped\\\",[58]],[[65110,65110],\\\"disallowed_STD3_mapped\\\",[63]],[[65111,65111],\\\"disallowed_STD3_mapped\\\",[33]],[[65112,65112],\\\"mapped\\\",[8212]],[[65113,65113],\\\"disallowed_STD3_mapped\\\",[40]],[[65114,65114],\\\"disallowed_STD3_mapped\\\",[41]],[[65115,65115],\\\"disallowed_STD3_mapped\\\",[123]],[[65116,65116],\\\"disallowed_STD3_mapped\\\",[125]],[[65117,65117],\\\"mapped\\\",[12308]],[[65118,65118],\\\"mapped\\\",[12309]],[[65119,65119],\\\"disallowed_STD3_mapped\\\",[35]],[[65120,65120],\\\"disallowed_STD3_mapped\\\",[38]],[[65121,65121],\\\"disallowed_STD3_mapped\\\",[42]],[[65122,65122],\\\"disallowed_STD3_mapped\\\",[43]],[[65123,65123],\\\"mapped\\\",[45]],[[65124,65124],\\\"disallowed_STD3_mapped\\\",[60]],[[65125,65125],\\\"disallowed_STD3_mapped\\\",[62]],[[65126,65126],\\\"disallowed_STD3_mapped\\\",[61]],[[65127,65127],\\\"disallowed\\\"],[[65128,65128],\\\"disallowed_STD3_mapped\\\",[92]],[[65129,65129],\\\"disallowed_STD3_mapped\\\",[36]],[[65130,65130],\\\"disallowed_STD3_mapped\\\",[37]],[[65131,65131],\\\"disallowed_STD3_mapped\\\",[64]],[[65132,65135],\\\"disallowed\\\"],[[65136,65136],\\\"disallowed_STD3_mapped\\\",[32,1611]],[[65137,65137],\\\"mapped\\\",[1600,1611]],[[65138,65138],\\\"disallowed_STD3_mapped\\\",[32,1612]],[[65139,65139],\\\"valid\\\"],[[65140,65140],\\\"disallowed_STD3_mapped\\\",[32,1613]],[[65141,65141],\\\"disallowed\\\"],[[65142,65142],\\\"disallowed_STD3_mapped\\\",[32,1614]],[[65143,65143],\\\"mapped\\\",[1600,1614]],[[65144,65144],\\\"disallowed_STD3_mapped\\\",[32,1615]],[[65145,65145],\\\"mapped\\\",[1600,1615]],[[65146,65146],\\\"disallowed_STD3_mapped\\\",[32,1616]],[[65147,65147],\\\"mapped\\\",[1600,1616]],[[65148,65148],\\\"disallowed_STD3_mapped\\\",[32,1617]],[[65149,65149],\\\"mapped\\\",[1600,1617]],[[65150,65150],\\\"disallowed_STD3_mapped\\\",[32,1618]],[[65151,65151],\\\"mapped\\\",[1600,1618]],[[65152,65152],\\\"mapped\\\",[1569]],[[65153,65154],\\\"mapped\\\",[1570]],[[65155,65156],\\\"mapped\\\",[1571]],[[65157,65158],\\\"mapped\\\",[1572]],[[65159,65160],\\\"mapped\\\",[1573]],[[65161,65164],\\\"mapped\\\",[1574]],[[65165,65166],\\\"mapped\\\",[1575]],[[65167,65170],\\\"mapped\\\",[1576]],[[65171,65172],\\\"mapped\\\",[1577]],[[65173,65176],\\\"mapped\\\",[1578]],[[65177,65180],\\\"mapped\\\",[1579]],[[65181,65184],\\\"mapped\\\",[1580]],[[65185,65188],\\\"mapped\\\",[1581]],[[65189,65192],\\\"mapped\\\",[1582]],[[65193,65194],\\\"mapped\\\",[1583]],[[65195,65196],\\\"mapped\\\",[1584]],[[65197,65198],\\\"mapped\\\",[1585]],[[65199,65200],\\\"mapped\\\",[1586]],[[65201,65204],\\\"mapped\\\",[1587]],[[65205,65208],\\\"mapped\\\",[1588]],[[65209,65212],\\\"mapped\\\",[1589]],[[65213,65216],\\\"mapped\\\",[1590]],[[65217,65220],\\\"mapped\\\",[1591]],[[65221,65224],\\\"mapped\\\",[1592]],[[65225,65228],\\\"mapped\\\",[1593]],[[65229,65232],\\\"mapped\\\",[1594]],[[65233,65236],\\\"mapped\\\",[1601]],[[65237,65240],\\\"mapped\\\",[1602]],[[65241,65244],\\\"mapped\\\",[1603]],[[65245,65248],\\\"mapped\\\",[1604]],[[65249,65252],\\\"mapped\\\",[1605]],[[65253,65256],\\\"mapped\\\",[1606]],[[65257,65260],\\\"mapped\\\",[1607]],[[65261,65262],\\\"mapped\\\",[1608]],[[65263,65264],\\\"mapped\\\",[1609]],[[65265,65268],\\\"mapped\\\",[1610]],[[65269,65270],\\\"mapped\\\",[1604,1570]],[[65271,65272],\\\"mapped\\\",[1604,1571]],[[65273,65274],\\\"mapped\\\",[1604,1573]],[[65275,65276],\\\"mapped\\\",[1604,1575]],[[65277,65278],\\\"disallowed\\\"],[[65279,65279],\\\"ignored\\\"],[[65280,65280],\\\"disallowed\\\"],[[65281,65281],\\\"disallowed_STD3_mapped\\\",[33]],[[65282,65282],\\\"disallowed_STD3_mapped\\\",[34]],[[65283,65283],\\\"disallowed_STD3_mapped\\\",[35]],[[65284,65284],\\\"disallowed_STD3_mapped\\\",[36]],[[65285,65285],\\\"disallowed_STD3_mapped\\\",[37]],[[65286,65286],\\\"disallowed_STD3_mapped\\\",[38]],[[65287,65287],\\\"disallowed_STD3_mapped\\\",[39]],[[65288,65288],\\\"disallowed_STD3_mapped\\\",[40]],[[65289,65289],\\\"disallowed_STD3_mapped\\\",[41]],[[65290,65290],\\\"disallowed_STD3_mapped\\\",[42]],[[65291,65291],\\\"disallowed_STD3_mapped\\\",[43]],[[65292,65292],\\\"disallowed_STD3_mapped\\\",[44]],[[65293,65293],\\\"mapped\\\",[45]],[[65294,65294],\\\"mapped\\\",[46]],[[65295,65295],\\\"disallowed_STD3_mapped\\\",[47]],[[65296,65296],\\\"mapped\\\",[48]],[[65297,65297],\\\"mapped\\\",[49]],[[65298,65298],\\\"mapped\\\",[50]],[[65299,65299],\\\"mapped\\\",[51]],[[65300,65300],\\\"mapped\\\",[52]],[[65301,65301],\\\"mapped\\\",[53]],[[65302,65302],\\\"mapped\\\",[54]],[[65303,65303],\\\"mapped\\\",[55]],[[65304,65304],\\\"mapped\\\",[56]],[[65305,65305],\\\"mapped\\\",[57]],[[65306,65306],\\\"disallowed_STD3_mapped\\\",[58]],[[65307,65307],\\\"disallowed_STD3_mapped\\\",[59]],[[65308,65308],\\\"disallowed_STD3_mapped\\\",[60]],[[65309,65309],\\\"disallowed_STD3_mapped\\\",[61]],[[65310,65310],\\\"disallowed_STD3_mapped\\\",[62]],[[65311,65311],\\\"disallowed_STD3_mapped\\\",[63]],[[65312,65312],\\\"disallowed_STD3_mapped\\\",[64]],[[65313,65313],\\\"mapped\\\",[97]],[[65314,65314],\\\"mapped\\\",[98]],[[65315,65315],\\\"mapped\\\",[99]],[[65316,65316],\\\"mapped\\\",[100]],[[65317,65317],\\\"mapped\\\",[101]],[[65318,65318],\\\"mapped\\\",[102]],[[65319,65319],\\\"mapped\\\",[103]],[[65320,65320],\\\"mapped\\\",[104]],[[65321,65321],\\\"mapped\\\",[105]],[[65322,65322],\\\"mapped\\\",[106]],[[65323,65323],\\\"mapped\\\",[107]],[[65324,65324],\\\"mapped\\\",[108]],[[65325,65325],\\\"mapped\\\",[109]],[[65326,65326],\\\"mapped\\\",[110]],[[65327,65327],\\\"mapped\\\",[111]],[[65328,65328],\\\"mapped\\\",[112]],[[65329,65329],\\\"mapped\\\",[113]],[[65330,65330],\\\"mapped\\\",[114]],[[65331,65331],\\\"mapped\\\",[115]],[[65332,65332],\\\"mapped\\\",[116]],[[65333,65333],\\\"mapped\\\",[117]],[[65334,65334],\\\"mapped\\\",[118]],[[65335,65335],\\\"mapped\\\",[119]],[[65336,65336],\\\"mapped\\\",[120]],[[65337,65337],\\\"mapped\\\",[121]],[[65338,65338],\\\"mapped\\\",[122]],[[65339,65339],\\\"disallowed_STD3_mapped\\\",[91]],[[65340,65340],\\\"disallowed_STD3_mapped\\\",[92]],[[65341,65341],\\\"disallowed_STD3_mapped\\\",[93]],[[65342,65342],\\\"disallowed_STD3_mapped\\\",[94]],[[65343,65343],\\\"disallowed_STD3_mapped\\\",[95]],[[65344,65344],\\\"disallowed_STD3_mapped\\\",[96]],[[65345,65345],\\\"mapped\\\",[97]],[[65346,65346],\\\"mapped\\\",[98]],[[65347,65347],\\\"mapped\\\",[99]],[[65348,65348],\\\"mapped\\\",[100]],[[65349,65349],\\\"mapped\\\",[101]],[[65350,65350],\\\"mapped\\\",[102]],[[65351,65351],\\\"mapped\\\",[103]],[[65352,65352],\\\"mapped\\\",[104]],[[65353,65353],\\\"mapped\\\",[105]],[[65354,65354],\\\"mapped\\\",[106]],[[65355,65355],\\\"mapped\\\",[107]],[[65356,65356],\\\"mapped\\\",[108]],[[65357,65357],\\\"mapped\\\",[109]],[[65358,65358],\\\"mapped\\\",[110]],[[65359,65359],\\\"mapped\\\",[111]],[[65360,65360],\\\"mapped\\\",[112]],[[65361,65361],\\\"mapped\\\",[113]],[[65362,65362],\\\"mapped\\\",[114]],[[65363,65363],\\\"mapped\\\",[115]],[[65364,65364],\\\"mapped\\\",[116]],[[65365,65365],\\\"mapped\\\",[117]],[[65366,65366],\\\"mapped\\\",[118]],[[65367,65367],\\\"mapped\\\",[119]],[[65368,65368],\\\"mapped\\\",[120]],[[65369,65369],\\\"mapped\\\",[121]],[[65370,65370],\\\"mapped\\\",[122]],[[65371,65371],\\\"disallowed_STD3_mapped\\\",[123]],[[65372,65372],\\\"disallowed_STD3_mapped\\\",[124]],[[65373,65373],\\\"disallowed_STD3_mapped\\\",[125]],[[65374,65374],\\\"disallowed_STD3_mapped\\\",[126]],[[65375,65375],\\\"mapped\\\",[10629]],[[65376,65376],\\\"mapped\\\",[10630]],[[65377,65377],\\\"mapped\\\",[46]],[[65378,65378],\\\"mapped\\\",[12300]],[[65379,65379],\\\"mapped\\\",[12301]],[[65380,65380],\\\"mapped\\\",[12289]],[[65381,65381],\\\"mapped\\\",[12539]],[[65382,65382],\\\"mapped\\\",[12530]],[[65383,65383],\\\"mapped\\\",[12449]],[[65384,65384],\\\"mapped\\\",[12451]],[[65385,65385],\\\"mapped\\\",[12453]],[[65386,65386],\\\"mapped\\\",[12455]],[[65387,65387],\\\"mapped\\\",[12457]],[[65388,65388],\\\"mapped\\\",[12515]],[[65389,65389],\\\"mapped\\\",[12517]],[[65390,65390],\\\"mapped\\\",[12519]],[[65391,65391],\\\"mapped\\\",[12483]],[[65392,65392],\\\"mapped\\\",[12540]],[[65393,65393],\\\"mapped\\\",[12450]],[[65394,65394],\\\"mapped\\\",[12452]],[[65395,65395],\\\"mapped\\\",[12454]],[[65396,65396],\\\"mapped\\\",[12456]],[[65397,65397],\\\"mapped\\\",[12458]],[[65398,65398],\\\"mapped\\\",[12459]],[[65399,65399],\\\"mapped\\\",[12461]],[[65400,65400],\\\"mapped\\\",[12463]],[[65401,65401],\\\"mapped\\\",[12465]],[[65402,65402],\\\"mapped\\\",[12467]],[[65403,65403],\\\"mapped\\\",[12469]],[[65404,65404],\\\"mapped\\\",[12471]],[[65405,65405],\\\"mapped\\\",[12473]],[[65406,65406],\\\"mapped\\\",[12475]],[[65407,65407],\\\"mapped\\\",[12477]],[[65408,65408],\\\"mapped\\\",[12479]],[[65409,65409],\\\"mapped\\\",[12481]],[[65410,65410],\\\"mapped\\\",[12484]],[[65411,65411],\\\"mapped\\\",[12486]],[[65412,65412],\\\"mapped\\\",[12488]],[[65413,65413],\\\"mapped\\\",[12490]],[[65414,65414],\\\"mapped\\\",[12491]],[[65415,65415],\\\"mapped\\\",[12492]],[[65416,65416],\\\"mapped\\\",[12493]],[[65417,65417],\\\"mapped\\\",[12494]],[[65418,65418],\\\"mapped\\\",[12495]],[[65419,65419],\\\"mapped\\\",[12498]],[[65420,65420],\\\"mapped\\\",[12501]],[[65421,65421],\\\"mapped\\\",[12504]],[[65422,65422],\\\"mapped\\\",[12507]],[[65423,65423],\\\"mapped\\\",[12510]],[[65424,65424],\\\"mapped\\\",[12511]],[[65425,65425],\\\"mapped\\\",[12512]],[[65426,65426],\\\"mapped\\\",[12513]],[[65427,65427],\\\"mapped\\\",[12514]],[[65428,65428],\\\"mapped\\\",[12516]],[[65429,65429],\\\"mapped\\\",[12518]],[[65430,65430],\\\"mapped\\\",[12520]],[[65431,65431],\\\"mapped\\\",[12521]],[[65432,65432],\\\"mapped\\\",[12522]],[[65433,65433],\\\"mapped\\\",[12523]],[[65434,65434],\\\"mapped\\\",[12524]],[[65435,65435],\\\"mapped\\\",[12525]],[[65436,65436],\\\"mapped\\\",[12527]],[[65437,65437],\\\"mapped\\\",[12531]],[[65438,65438],\\\"mapped\\\",[12441]],[[65439,65439],\\\"mapped\\\",[12442]],[[65440,65440],\\\"disallowed\\\"],[[65441,65441],\\\"mapped\\\",[4352]],[[65442,65442],\\\"mapped\\\",[4353]],[[65443,65443],\\\"mapped\\\",[4522]],[[65444,65444],\\\"mapped\\\",[4354]],[[65445,65445],\\\"mapped\\\",[4524]],[[65446,65446],\\\"mapped\\\",[4525]],[[65447,65447],\\\"mapped\\\",[4355]],[[65448,65448],\\\"mapped\\\",[4356]],[[65449,65449],\\\"mapped\\\",[4357]],[[65450,65450],\\\"mapped\\\",[4528]],[[65451,65451],\\\"mapped\\\",[4529]],[[65452,65452],\\\"mapped\\\",[4530]],[[65453,65453],\\\"mapped\\\",[4531]],[[65454,65454],\\\"mapped\\\",[4532]],[[65455,65455],\\\"mapped\\\",[4533]],[[65456,65456],\\\"mapped\\\",[4378]],[[65457,65457],\\\"mapped\\\",[4358]],[[65458,65458],\\\"mapped\\\",[4359]],[[65459,65459],\\\"mapped\\\",[4360]],[[65460,65460],\\\"mapped\\\",[4385]],[[65461,65461],\\\"mapped\\\",[4361]],[[65462,65462],\\\"mapped\\\",[4362]],[[65463,65463],\\\"mapped\\\",[4363]],[[65464,65464],\\\"mapped\\\",[4364]],[[65465,65465],\\\"mapped\\\",[4365]],[[65466,65466],\\\"mapped\\\",[4366]],[[65467,65467],\\\"mapped\\\",[4367]],[[65468,65468],\\\"mapped\\\",[4368]],[[65469,65469],\\\"mapped\\\",[4369]],[[65470,65470],\\\"mapped\\\",[4370]],[[65471,65473],\\\"disallowed\\\"],[[65474,65474],\\\"mapped\\\",[4449]],[[65475,65475],\\\"mapped\\\",[4450]],[[65476,65476],\\\"mapped\\\",[4451]],[[65477,65477],\\\"mapped\\\",[4452]],[[65478,65478],\\\"mapped\\\",[4453]],[[65479,65479],\\\"mapped\\\",[4454]],[[65480,65481],\\\"disallowed\\\"],[[65482,65482],\\\"mapped\\\",[4455]],[[65483,65483],\\\"mapped\\\",[4456]],[[65484,65484],\\\"mapped\\\",[4457]],[[65485,65485],\\\"mapped\\\",[4458]],[[65486,65486],\\\"mapped\\\",[4459]],[[65487,65487],\\\"mapped\\\",[4460]],[[65488,65489],\\\"disallowed\\\"],[[65490,65490],\\\"mapped\\\",[4461]],[[65491,65491],\\\"mapped\\\",[4462]],[[65492,65492],\\\"mapped\\\",[4463]],[[65493,65493],\\\"mapped\\\",[4464]],[[65494,65494],\\\"mapped\\\",[4465]],[[65495,65495],\\\"mapped\\\",[4466]],[[65496,65497],\\\"disallowed\\\"],[[65498,65498],\\\"mapped\\\",[4467]],[[65499,65499],\\\"mapped\\\",[4468]],[[65500,65500],\\\"mapped\\\",[4469]],[[65501,65503],\\\"disallowed\\\"],[[65504,65504],\\\"mapped\\\",[162]],[[65505,65505],\\\"mapped\\\",[163]],[[65506,65506],\\\"mapped\\\",[172]],[[65507,65507],\\\"disallowed_STD3_mapped\\\",[32,772]],[[65508,65508],\\\"mapped\\\",[166]],[[65509,65509],\\\"mapped\\\",[165]],[[65510,65510],\\\"mapped\\\",[8361]],[[65511,65511],\\\"disallowed\\\"],[[65512,65512],\\\"mapped\\\",[9474]],[[65513,65513],\\\"mapped\\\",[8592]],[[65514,65514],\\\"mapped\\\",[8593]],[[65515,65515],\\\"mapped\\\",[8594]],[[65516,65516],\\\"mapped\\\",[8595]],[[65517,65517],\\\"mapped\\\",[9632]],[[65518,65518],\\\"mapped\\\",[9675]],[[65519,65528],\\\"disallowed\\\"],[[65529,65531],\\\"disallowed\\\"],[[65532,65532],\\\"disallowed\\\"],[[65533,65533],\\\"disallowed\\\"],[[65534,65535],\\\"disallowed\\\"],[[65536,65547],\\\"valid\\\"],[[65548,65548],\\\"disallowed\\\"],[[65549,65574],\\\"valid\\\"],[[65575,65575],\\\"disallowed\\\"],[[65576,65594],\\\"valid\\\"],[[65595,65595],\\\"disallowed\\\"],[[65596,65597],\\\"valid\\\"],[[65598,65598],\\\"disallowed\\\"],[[65599,65613],\\\"valid\\\"],[[65614,65615],\\\"disallowed\\\"],[[65616,65629],\\\"valid\\\"],[[65630,65663],\\\"disallowed\\\"],[[65664,65786],\\\"valid\\\"],[[65787,65791],\\\"disallowed\\\"],[[65792,65794],\\\"valid\\\",[],\\\"NV8\\\"],[[65795,65798],\\\"disallowed\\\"],[[65799,65843],\\\"valid\\\",[],\\\"NV8\\\"],[[65844,65846],\\\"disallowed\\\"],[[65847,65855],\\\"valid\\\",[],\\\"NV8\\\"],[[65856,65930],\\\"valid\\\",[],\\\"NV8\\\"],[[65931,65932],\\\"valid\\\",[],\\\"NV8\\\"],[[65933,65935],\\\"disallowed\\\"],[[65936,65947],\\\"valid\\\",[],\\\"NV8\\\"],[[65948,65951],\\\"disallowed\\\"],[[65952,65952],\\\"valid\\\",[],\\\"NV8\\\"],[[65953,65999],\\\"disallowed\\\"],[[66000,66044],\\\"valid\\\",[],\\\"NV8\\\"],[[66045,66045],\\\"valid\\\"],[[66046,66175],\\\"disallowed\\\"],[[66176,66204],\\\"valid\\\"],[[66205,66207],\\\"disallowed\\\"],[[66208,66256],\\\"valid\\\"],[[66257,66271],\\\"disallowed\\\"],[[66272,66272],\\\"valid\\\"],[[66273,66299],\\\"valid\\\",[],\\\"NV8\\\"],[[66300,66303],\\\"disallowed\\\"],[[66304,66334],\\\"valid\\\"],[[66335,66335],\\\"valid\\\"],[[66336,66339],\\\"valid\\\",[],\\\"NV8\\\"],[[66340,66351],\\\"disallowed\\\"],[[66352,66368],\\\"valid\\\"],[[66369,66369],\\\"valid\\\",[],\\\"NV8\\\"],[[66370,66377],\\\"valid\\\"],[[66378,66378],\\\"valid\\\",[],\\\"NV8\\\"],[[66379,66383],\\\"disallowed\\\"],[[66384,66426],\\\"valid\\\"],[[66427,66431],\\\"disallowed\\\"],[[66432,66461],\\\"valid\\\"],[[66462,66462],\\\"disallowed\\\"],[[66463,66463],\\\"valid\\\",[],\\\"NV8\\\"],[[66464,66499],\\\"valid\\\"],[[66500,66503],\\\"disallowed\\\"],[[66504,66511],\\\"valid\\\"],[[66512,66517],\\\"valid\\\",[],\\\"NV8\\\"],[[66518,66559],\\\"disallowed\\\"],[[66560,66560],\\\"mapped\\\",[66600]],[[66561,66561],\\\"mapped\\\",[66601]],[[66562,66562],\\\"mapped\\\",[66602]],[[66563,66563],\\\"mapped\\\",[66603]],[[66564,66564],\\\"mapped\\\",[66604]],[[66565,66565],\\\"mapped\\\",[66605]],[[66566,66566],\\\"mapped\\\",[66606]],[[66567,66567],\\\"mapped\\\",[66607]],[[66568,66568],\\\"mapped\\\",[66608]],[[66569,66569],\\\"mapped\\\",[66609]],[[66570,66570],\\\"mapped\\\",[66610]],[[66571,66571],\\\"mapped\\\",[66611]],[[66572,66572],\\\"mapped\\\",[66612]],[[66573,66573],\\\"mapped\\\",[66613]],[[66574,66574],\\\"mapped\\\",[66614]],[[66575,66575],\\\"mapped\\\",[66615]],[[66576,66576],\\\"mapped\\\",[66616]],[[66577,66577],\\\"mapped\\\",[66617]],[[66578,66578],\\\"mapped\\\",[66618]],[[66579,66579],\\\"mapped\\\",[66619]],[[66580,66580],\\\"mapped\\\",[66620]],[[66581,66581],\\\"mapped\\\",[66621]],[[66582,66582],\\\"mapped\\\",[66622]],[[66583,66583],\\\"mapped\\\",[66623]],[[66584,66584],\\\"mapped\\\",[66624]],[[66585,66585],\\\"mapped\\\",[66625]],[[66586,66586],\\\"mapped\\\",[66626]],[[66587,66587],\\\"mapped\\\",[66627]],[[66588,66588],\\\"mapped\\\",[66628]],[[66589,66589],\\\"mapped\\\",[66629]],[[66590,66590],\\\"mapped\\\",[66630]],[[66591,66591],\\\"mapped\\\",[66631]],[[66592,66592],\\\"mapped\\\",[66632]],[[66593,66593],\\\"mapped\\\",[66633]],[[66594,66594],\\\"mapped\\\",[66634]],[[66595,66595],\\\"mapped\\\",[66635]],[[66596,66596],\\\"mapped\\\",[66636]],[[66597,66597],\\\"mapped\\\",[66637]],[[66598,66598],\\\"mapped\\\",[66638]],[[66599,66599],\\\"mapped\\\",[66639]],[[66600,66637],\\\"valid\\\"],[[66638,66717],\\\"valid\\\"],[[66718,66719],\\\"disallowed\\\"],[[66720,66729],\\\"valid\\\"],[[66730,66815],\\\"disallowed\\\"],[[66816,66855],\\\"valid\\\"],[[66856,66863],\\\"disallowed\\\"],[[66864,66915],\\\"valid\\\"],[[66916,66926],\\\"disallowed\\\"],[[66927,66927],\\\"valid\\\",[],\\\"NV8\\\"],[[66928,67071],\\\"disallowed\\\"],[[67072,67382],\\\"valid\\\"],[[67383,67391],\\\"disallowed\\\"],[[67392,67413],\\\"valid\\\"],[[67414,67423],\\\"disallowed\\\"],[[67424,67431],\\\"valid\\\"],[[67432,67583],\\\"disallowed\\\"],[[67584,67589],\\\"valid\\\"],[[67590,67591],\\\"disallowed\\\"],[[67592,67592],\\\"valid\\\"],[[67593,67593],\\\"disallowed\\\"],[[67594,67637],\\\"valid\\\"],[[67638,67638],\\\"disallowed\\\"],[[67639,67640],\\\"valid\\\"],[[67641,67643],\\\"disallowed\\\"],[[67644,67644],\\\"valid\\\"],[[67645,67646],\\\"disallowed\\\"],[[67647,67647],\\\"valid\\\"],[[67648,67669],\\\"valid\\\"],[[67670,67670],\\\"disallowed\\\"],[[67671,67679],\\\"valid\\\",[],\\\"NV8\\\"],[[67680,67702],\\\"valid\\\"],[[67703,67711],\\\"valid\\\",[],\\\"NV8\\\"],[[67712,67742],\\\"valid\\\"],[[67743,67750],\\\"disallowed\\\"],[[67751,67759],\\\"valid\\\",[],\\\"NV8\\\"],[[67760,67807],\\\"disallowed\\\"],[[67808,67826],\\\"valid\\\"],[[67827,67827],\\\"disallowed\\\"],[[67828,67829],\\\"valid\\\"],[[67830,67834],\\\"disallowed\\\"],[[67835,67839],\\\"valid\\\",[],\\\"NV8\\\"],[[67840,67861],\\\"valid\\\"],[[67862,67865],\\\"valid\\\",[],\\\"NV8\\\"],[[67866,67867],\\\"valid\\\",[],\\\"NV8\\\"],[[67868,67870],\\\"disallowed\\\"],[[67871,67871],\\\"valid\\\",[],\\\"NV8\\\"],[[67872,67897],\\\"valid\\\"],[[67898,67902],\\\"disallowed\\\"],[[67903,67903],\\\"valid\\\",[],\\\"NV8\\\"],[[67904,67967],\\\"disallowed\\\"],[[67968,68023],\\\"valid\\\"],[[68024,68027],\\\"disallowed\\\"],[[68028,68029],\\\"valid\\\",[],\\\"NV8\\\"],[[68030,68031],\\\"valid\\\"],[[68032,68047],\\\"valid\\\",[],\\\"NV8\\\"],[[68048,68049],\\\"disallowed\\\"],[[68050,68095],\\\"valid\\\",[],\\\"NV8\\\"],[[68096,68099],\\\"valid\\\"],[[68100,68100],\\\"disallowed\\\"],[[68101,68102],\\\"valid\\\"],[[68103,68107],\\\"disallowed\\\"],[[68108,68115],\\\"valid\\\"],[[68116,68116],\\\"disallowed\\\"],[[68117,68119],\\\"valid\\\"],[[68120,68120],\\\"disallowed\\\"],[[68121,68147],\\\"valid\\\"],[[68148,68151],\\\"disallowed\\\"],[[68152,68154],\\\"valid\\\"],[[68155,68158],\\\"disallowed\\\"],[[68159,68159],\\\"valid\\\"],[[68160,68167],\\\"valid\\\",[],\\\"NV8\\\"],[[68168,68175],\\\"disallowed\\\"],[[68176,68184],\\\"valid\\\",[],\\\"NV8\\\"],[[68185,68191],\\\"disallowed\\\"],[[68192,68220],\\\"valid\\\"],[[68221,68223],\\\"valid\\\",[],\\\"NV8\\\"],[[68224,68252],\\\"valid\\\"],[[68253,68255],\\\"valid\\\",[],\\\"NV8\\\"],[[68256,68287],\\\"disallowed\\\"],[[68288,68295],\\\"valid\\\"],[[68296,68296],\\\"valid\\\",[],\\\"NV8\\\"],[[68297,68326],\\\"valid\\\"],[[68327,68330],\\\"disallowed\\\"],[[68331,68342],\\\"valid\\\",[],\\\"NV8\\\"],[[68343,68351],\\\"disallowed\\\"],[[68352,68405],\\\"valid\\\"],[[68406,68408],\\\"disallowed\\\"],[[68409,68415],\\\"valid\\\",[],\\\"NV8\\\"],[[68416,68437],\\\"valid\\\"],[[68438,68439],\\\"disallowed\\\"],[[68440,68447],\\\"valid\\\",[],\\\"NV8\\\"],[[68448,68466],\\\"valid\\\"],[[68467,68471],\\\"disallowed\\\"],[[68472,68479],\\\"valid\\\",[],\\\"NV8\\\"],[[68480,68497],\\\"valid\\\"],[[68498,68504],\\\"disallowed\\\"],[[68505,68508],\\\"valid\\\",[],\\\"NV8\\\"],[[68509,68520],\\\"disallowed\\\"],[[68521,68527],\\\"valid\\\",[],\\\"NV8\\\"],[[68528,68607],\\\"disallowed\\\"],[[68608,68680],\\\"valid\\\"],[[68681,68735],\\\"disallowed\\\"],[[68736,68736],\\\"mapped\\\",[68800]],[[68737,68737],\\\"mapped\\\",[68801]],[[68738,68738],\\\"mapped\\\",[68802]],[[68739,68739],\\\"mapped\\\",[68803]],[[68740,68740],\\\"mapped\\\",[68804]],[[68741,68741],\\\"mapped\\\",[68805]],[[68742,68742],\\\"mapped\\\",[68806]],[[68743,68743],\\\"mapped\\\",[68807]],[[68744,68744],\\\"mapped\\\",[68808]],[[68745,68745],\\\"mapped\\\",[68809]],[[68746,68746],\\\"mapped\\\",[68810]],[[68747,68747],\\\"mapped\\\",[68811]],[[68748,68748],\\\"mapped\\\",[68812]],[[68749,68749],\\\"mapped\\\",[68813]],[[68750,68750],\\\"mapped\\\",[68814]],[[68751,68751],\\\"mapped\\\",[68815]],[[68752,68752],\\\"mapped\\\",[68816]],[[68753,68753],\\\"mapped\\\",[68817]],[[68754,68754],\\\"mapped\\\",[68818]],[[68755,68755],\\\"mapped\\\",[68819]],[[68756,68756],\\\"mapped\\\",[68820]],[[68757,68757],\\\"mapped\\\",[68821]],[[68758,68758],\\\"mapped\\\",[68822]],[[68759,68759],\\\"mapped\\\",[68823]],[[68760,68760],\\\"mapped\\\",[68824]],[[68761,68761],\\\"mapped\\\",[68825]],[[68762,68762],\\\"mapped\\\",[68826]],[[68763,68763],\\\"mapped\\\",[68827]],[[68764,68764],\\\"mapped\\\",[68828]],[[68765,68765],\\\"mapped\\\",[68829]],[[68766,68766],\\\"mapped\\\",[68830]],[[68767,68767],\\\"mapped\\\",[68831]],[[68768,68768],\\\"mapped\\\",[68832]],[[68769,68769],\\\"mapped\\\",[68833]],[[68770,68770],\\\"mapped\\\",[68834]],[[68771,68771],\\\"mapped\\\",[68835]],[[68772,68772],\\\"mapped\\\",[68836]],[[68773,68773],\\\"mapped\\\",[68837]],[[68774,68774],\\\"mapped\\\",[68838]],[[68775,68775],\\\"mapped\\\",[68839]],[[68776,68776],\\\"mapped\\\",[68840]],[[68777,68777],\\\"mapped\\\",[68841]],[[68778,68778],\\\"mapped\\\",[68842]],[[68779,68779],\\\"mapped\\\",[68843]],[[68780,68780],\\\"mapped\\\",[68844]],[[68781,68781],\\\"mapped\\\",[68845]],[[68782,68782],\\\"mapped\\\",[68846]],[[68783,68783],\\\"mapped\\\",[68847]],[[68784,68784],\\\"mapped\\\",[68848]],[[68785,68785],\\\"mapped\\\",[68849]],[[68786,68786],\\\"mapped\\\",[68850]],[[68787,68799],\\\"disallowed\\\"],[[68800,68850],\\\"valid\\\"],[[68851,68857],\\\"disallowed\\\"],[[68858,68863],\\\"valid\\\",[],\\\"NV8\\\"],[[68864,69215],\\\"disallowed\\\"],[[69216,69246],\\\"valid\\\",[],\\\"NV8\\\"],[[69247,69631],\\\"disallowed\\\"],[[69632,69702],\\\"valid\\\"],[[69703,69709],\\\"valid\\\",[],\\\"NV8\\\"],[[69710,69713],\\\"disallowed\\\"],[[69714,69733],\\\"valid\\\",[],\\\"NV8\\\"],[[69734,69743],\\\"valid\\\"],[[69744,69758],\\\"disallowed\\\"],[[69759,69759],\\\"valid\\\"],[[69760,69818],\\\"valid\\\"],[[69819,69820],\\\"valid\\\",[],\\\"NV8\\\"],[[69821,69821],\\\"disallowed\\\"],[[69822,69825],\\\"valid\\\",[],\\\"NV8\\\"],[[69826,69839],\\\"disallowed\\\"],[[69840,69864],\\\"valid\\\"],[[69865,69871],\\\"disallowed\\\"],[[69872,69881],\\\"valid\\\"],[[69882,69887],\\\"disallowed\\\"],[[69888,69940],\\\"valid\\\"],[[69941,69941],\\\"disallowed\\\"],[[69942,69951],\\\"valid\\\"],[[69952,69955],\\\"valid\\\",[],\\\"NV8\\\"],[[69956,69967],\\\"disallowed\\\"],[[69968,70003],\\\"valid\\\"],[[70004,70005],\\\"valid\\\",[],\\\"NV8\\\"],[[70006,70006],\\\"valid\\\"],[[70007,70015],\\\"disallowed\\\"],[[70016,70084],\\\"valid\\\"],[[70085,70088],\\\"valid\\\",[],\\\"NV8\\\"],[[70089,70089],\\\"valid\\\",[],\\\"NV8\\\"],[[70090,70092],\\\"valid\\\"],[[70093,70093],\\\"valid\\\",[],\\\"NV8\\\"],[[70094,70095],\\\"disallowed\\\"],[[70096,70105],\\\"valid\\\"],[[70106,70106],\\\"valid\\\"],[[70107,70107],\\\"valid\\\",[],\\\"NV8\\\"],[[70108,70108],\\\"valid\\\"],[[70109,70111],\\\"valid\\\",[],\\\"NV8\\\"],[[70112,70112],\\\"disallowed\\\"],[[70113,70132],\\\"valid\\\",[],\\\"NV8\\\"],[[70133,70143],\\\"disallowed\\\"],[[70144,70161],\\\"valid\\\"],[[70162,70162],\\\"disallowed\\\"],[[70163,70199],\\\"valid\\\"],[[70200,70205],\\\"valid\\\",[],\\\"NV8\\\"],[[70206,70271],\\\"disallowed\\\"],[[70272,70278],\\\"valid\\\"],[[70279,70279],\\\"disallowed\\\"],[[70280,70280],\\\"valid\\\"],[[70281,70281],\\\"disallowed\\\"],[[70282,70285],\\\"valid\\\"],[[70286,70286],\\\"disallowed\\\"],[[70287,70301],\\\"valid\\\"],[[70302,70302],\\\"disallowed\\\"],[[70303,70312],\\\"valid\\\"],[[70313,70313],\\\"valid\\\",[],\\\"NV8\\\"],[[70314,70319],\\\"disallowed\\\"],[[70320,70378],\\\"valid\\\"],[[70379,70383],\\\"disallowed\\\"],[[70384,70393],\\\"valid\\\"],[[70394,70399],\\\"disallowed\\\"],[[70400,70400],\\\"valid\\\"],[[70401,70403],\\\"valid\\\"],[[70404,70404],\\\"disallowed\\\"],[[70405,70412],\\\"valid\\\"],[[70413,70414],\\\"disallowed\\\"],[[70415,70416],\\\"valid\\\"],[[70417,70418],\\\"disallowed\\\"],[[70419,70440],\\\"valid\\\"],[[70441,70441],\\\"disallowed\\\"],[[70442,70448],\\\"valid\\\"],[[70449,70449],\\\"disallowed\\\"],[[70450,70451],\\\"valid\\\"],[[70452,70452],\\\"disallowed\\\"],[[70453,70457],\\\"valid\\\"],[[70458,70459],\\\"disallowed\\\"],[[70460,70468],\\\"valid\\\"],[[70469,70470],\\\"disallowed\\\"],[[70471,70472],\\\"valid\\\"],[[70473,70474],\\\"disallowed\\\"],[[70475,70477],\\\"valid\\\"],[[70478,70479],\\\"disallowed\\\"],[[70480,70480],\\\"valid\\\"],[[70481,70486],\\\"disallowed\\\"],[[70487,70487],\\\"valid\\\"],[[70488,70492],\\\"disallowed\\\"],[[70493,70499],\\\"valid\\\"],[[70500,70501],\\\"disallowed\\\"],[[70502,70508],\\\"valid\\\"],[[70509,70511],\\\"disallowed\\\"],[[70512,70516],\\\"valid\\\"],[[70517,70783],\\\"disallowed\\\"],[[70784,70853],\\\"valid\\\"],[[70854,70854],\\\"valid\\\",[],\\\"NV8\\\"],[[70855,70855],\\\"valid\\\"],[[70856,70863],\\\"disallowed\\\"],[[70864,70873],\\\"valid\\\"],[[70874,71039],\\\"disallowed\\\"],[[71040,71093],\\\"valid\\\"],[[71094,71095],\\\"disallowed\\\"],[[71096,71104],\\\"valid\\\"],[[71105,71113],\\\"valid\\\",[],\\\"NV8\\\"],[[71114,71127],\\\"valid\\\",[],\\\"NV8\\\"],[[71128,71133],\\\"valid\\\"],[[71134,71167],\\\"disallowed\\\"],[[71168,71232],\\\"valid\\\"],[[71233,71235],\\\"valid\\\",[],\\\"NV8\\\"],[[71236,71236],\\\"valid\\\"],[[71237,71247],\\\"disallowed\\\"],[[71248,71257],\\\"valid\\\"],[[71258,71295],\\\"disallowed\\\"],[[71296,71351],\\\"valid\\\"],[[71352,71359],\\\"disallowed\\\"],[[71360,71369],\\\"valid\\\"],[[71370,71423],\\\"disallowed\\\"],[[71424,71449],\\\"valid\\\"],[[71450,71452],\\\"disallowed\\\"],[[71453,71467],\\\"valid\\\"],[[71468,71471],\\\"disallowed\\\"],[[71472,71481],\\\"valid\\\"],[[71482,71487],\\\"valid\\\",[],\\\"NV8\\\"],[[71488,71839],\\\"disallowed\\\"],[[71840,71840],\\\"mapped\\\",[71872]],[[71841,71841],\\\"mapped\\\",[71873]],[[71842,71842],\\\"mapped\\\",[71874]],[[71843,71843],\\\"mapped\\\",[71875]],[[71844,71844],\\\"mapped\\\",[71876]],[[71845,71845],\\\"mapped\\\",[71877]],[[71846,71846],\\\"mapped\\\",[71878]],[[71847,71847],\\\"mapped\\\",[71879]],[[71848,71848],\\\"mapped\\\",[71880]],[[71849,71849],\\\"mapped\\\",[71881]],[[71850,71850],\\\"mapped\\\",[71882]],[[71851,71851],\\\"mapped\\\",[71883]],[[71852,71852],\\\"mapped\\\",[71884]],[[71853,71853],\\\"mapped\\\",[71885]],[[71854,71854],\\\"mapped\\\",[71886]],[[71855,71855],\\\"mapped\\\",[71887]],[[71856,71856],\\\"mapped\\\",[71888]],[[71857,71857],\\\"mapped\\\",[71889]],[[71858,71858],\\\"mapped\\\",[71890]],[[71859,71859],\\\"mapped\\\",[71891]],[[71860,71860],\\\"mapped\\\",[71892]],[[71861,71861],\\\"mapped\\\",[71893]],[[71862,71862],\\\"mapped\\\",[71894]],[[71863,71863],\\\"mapped\\\",[71895]],[[71864,71864],\\\"mapped\\\",[71896]],[[71865,71865],\\\"mapped\\\",[71897]],[[71866,71866],\\\"mapped\\\",[71898]],[[71867,71867],\\\"mapped\\\",[71899]],[[71868,71868],\\\"mapped\\\",[71900]],[[71869,71869],\\\"mapped\\\",[71901]],[[71870,71870],\\\"mapped\\\",[71902]],[[71871,71871],\\\"mapped\\\",[71903]],[[71872,71913],\\\"valid\\\"],[[71914,71922],\\\"valid\\\",[],\\\"NV8\\\"],[[71923,71934],\\\"disallowed\\\"],[[71935,71935],\\\"valid\\\"],[[71936,72383],\\\"disallowed\\\"],[[72384,72440],\\\"valid\\\"],[[72441,73727],\\\"disallowed\\\"],[[73728,74606],\\\"valid\\\"],[[74607,74648],\\\"valid\\\"],[[74649,74649],\\\"valid\\\"],[[74650,74751],\\\"disallowed\\\"],[[74752,74850],\\\"valid\\\",[],\\\"NV8\\\"],[[74851,74862],\\\"valid\\\",[],\\\"NV8\\\"],[[74863,74863],\\\"disallowed\\\"],[[74864,74867],\\\"valid\\\",[],\\\"NV8\\\"],[[74868,74868],\\\"valid\\\",[],\\\"NV8\\\"],[[74869,74879],\\\"disallowed\\\"],[[74880,75075],\\\"valid\\\"],[[75076,77823],\\\"disallowed\\\"],[[77824,78894],\\\"valid\\\"],[[78895,82943],\\\"disallowed\\\"],[[82944,83526],\\\"valid\\\"],[[83527,92159],\\\"disallowed\\\"],[[92160,92728],\\\"valid\\\"],[[92729,92735],\\\"disallowed\\\"],[[92736,92766],\\\"valid\\\"],[[92767,92767],\\\"disallowed\\\"],[[92768,92777],\\\"valid\\\"],[[92778,92781],\\\"disallowed\\\"],[[92782,92783],\\\"valid\\\",[],\\\"NV8\\\"],[[92784,92879],\\\"disallowed\\\"],[[92880,92909],\\\"valid\\\"],[[92910,92911],\\\"disallowed\\\"],[[92912,92916],\\\"valid\\\"],[[92917,92917],\\\"valid\\\",[],\\\"NV8\\\"],[[92918,92927],\\\"disallowed\\\"],[[92928,92982],\\\"valid\\\"],[[92983,92991],\\\"valid\\\",[],\\\"NV8\\\"],[[92992,92995],\\\"valid\\\"],[[92996,92997],\\\"valid\\\",[],\\\"NV8\\\"],[[92998,93007],\\\"disallowed\\\"],[[93008,93017],\\\"valid\\\"],[[93018,93018],\\\"disallowed\\\"],[[93019,93025],\\\"valid\\\",[],\\\"NV8\\\"],[[93026,93026],\\\"disallowed\\\"],[[93027,93047],\\\"valid\\\"],[[93048,93052],\\\"disallowed\\\"],[[93053,93071],\\\"valid\\\"],[[93072,93951],\\\"disallowed\\\"],[[93952,94020],\\\"valid\\\"],[[94021,94031],\\\"disallowed\\\"],[[94032,94078],\\\"valid\\\"],[[94079,94094],\\\"disallowed\\\"],[[94095,94111],\\\"valid\\\"],[[94112,110591],\\\"disallowed\\\"],[[110592,110593],\\\"valid\\\"],[[110594,113663],\\\"disallowed\\\"],[[113664,113770],\\\"valid\\\"],[[113771,113775],\\\"disallowed\\\"],[[113776,113788],\\\"valid\\\"],[[113789,113791],\\\"disallowed\\\"],[[113792,113800],\\\"valid\\\"],[[113801,113807],\\\"disallowed\\\"],[[113808,113817],\\\"valid\\\"],[[113818,113819],\\\"disallowed\\\"],[[113820,113820],\\\"valid\\\",[],\\\"NV8\\\"],[[113821,113822],\\\"valid\\\"],[[113823,113823],\\\"valid\\\",[],\\\"NV8\\\"],[[113824,113827],\\\"ignored\\\"],[[113828,118783],\\\"disallowed\\\"],[[118784,119029],\\\"valid\\\",[],\\\"NV8\\\"],[[119030,119039],\\\"disallowed\\\"],[[119040,119078],\\\"valid\\\",[],\\\"NV8\\\"],[[119079,119080],\\\"disallowed\\\"],[[119081,119081],\\\"valid\\\",[],\\\"NV8\\\"],[[119082,119133],\\\"valid\\\",[],\\\"NV8\\\"],[[119134,119134],\\\"mapped\\\",[119127,119141]],[[119135,119135],\\\"mapped\\\",[119128,119141]],[[119136,119136],\\\"mapped\\\",[119128,119141,119150]],[[119137,119137],\\\"mapped\\\",[119128,119141,119151]],[[119138,119138],\\\"mapped\\\",[119128,119141,119152]],[[119139,119139],\\\"mapped\\\",[119128,119141,119153]],[[119140,119140],\\\"mapped\\\",[119128,119141,119154]],[[119141,119154],\\\"valid\\\",[],\\\"NV8\\\"],[[119155,119162],\\\"disallowed\\\"],[[119163,119226],\\\"valid\\\",[],\\\"NV8\\\"],[[119227,119227],\\\"mapped\\\",[119225,119141]],[[119228,119228],\\\"mapped\\\",[119226,119141]],[[119229,119229],\\\"mapped\\\",[119225,119141,119150]],[[119230,119230],\\\"mapped\\\",[119226,119141,119150]],[[119231,119231],\\\"mapped\\\",[119225,119141,119151]],[[119232,119232],\\\"mapped\\\",[119226,119141,119151]],[[119233,119261],\\\"valid\\\",[],\\\"NV8\\\"],[[119262,119272],\\\"valid\\\",[],\\\"NV8\\\"],[[119273,119295],\\\"disallowed\\\"],[[119296,119365],\\\"valid\\\",[],\\\"NV8\\\"],[[119366,119551],\\\"disallowed\\\"],[[119552,119638],\\\"valid\\\",[],\\\"NV8\\\"],[[119639,119647],\\\"disallowed\\\"],[[119648,119665],\\\"valid\\\",[],\\\"NV8\\\"],[[119666,119807],\\\"disallowed\\\"],[[119808,119808],\\\"mapped\\\",[97]],[[119809,119809],\\\"mapped\\\",[98]],[[119810,119810],\\\"mapped\\\",[99]],[[119811,119811],\\\"mapped\\\",[100]],[[119812,119812],\\\"mapped\\\",[101]],[[119813,119813],\\\"mapped\\\",[102]],[[119814,119814],\\\"mapped\\\",[103]],[[119815,119815],\\\"mapped\\\",[104]],[[119816,119816],\\\"mapped\\\",[105]],[[119817,119817],\\\"mapped\\\",[106]],[[119818,119818],\\\"mapped\\\",[107]],[[119819,119819],\\\"mapped\\\",[108]],[[119820,119820],\\\"mapped\\\",[109]],[[119821,119821],\\\"mapped\\\",[110]],[[119822,119822],\\\"mapped\\\",[111]],[[119823,119823],\\\"mapped\\\",[112]],[[119824,119824],\\\"mapped\\\",[113]],[[119825,119825],\\\"mapped\\\",[114]],[[119826,119826],\\\"mapped\\\",[115]],[[119827,119827],\\\"mapped\\\",[116]],[[119828,119828],\\\"mapped\\\",[117]],[[119829,119829],\\\"mapped\\\",[118]],[[119830,119830],\\\"mapped\\\",[119]],[[119831,119831],\\\"mapped\\\",[120]],[[119832,119832],\\\"mapped\\\",[121]],[[119833,119833],\\\"mapped\\\",[122]],[[119834,119834],\\\"mapped\\\",[97]],[[119835,119835],\\\"mapped\\\",[98]],[[119836,119836],\\\"mapped\\\",[99]],[[119837,119837],\\\"mapped\\\",[100]],[[119838,119838],\\\"mapped\\\",[101]],[[119839,119839],\\\"mapped\\\",[102]],[[119840,119840],\\\"mapped\\\",[103]],[[119841,119841],\\\"mapped\\\",[104]],[[119842,119842],\\\"mapped\\\",[105]],[[119843,119843],\\\"mapped\\\",[106]],[[119844,119844],\\\"mapped\\\",[107]],[[119845,119845],\\\"mapped\\\",[108]],[[119846,119846],\\\"mapped\\\",[109]],[[119847,119847],\\\"mapped\\\",[110]],[[119848,119848],\\\"mapped\\\",[111]],[[119849,119849],\\\"mapped\\\",[112]],[[119850,119850],\\\"mapped\\\",[113]],[[119851,119851],\\\"mapped\\\",[114]],[[119852,119852],\\\"mapped\\\",[115]],[[119853,119853],\\\"mapped\\\",[116]],[[119854,119854],\\\"mapped\\\",[117]],[[119855,119855],\\\"mapped\\\",[118]],[[119856,119856],\\\"mapped\\\",[119]],[[119857,119857],\\\"mapped\\\",[120]],[[119858,119858],\\\"mapped\\\",[121]],[[119859,119859],\\\"mapped\\\",[122]],[[119860,119860],\\\"mapped\\\",[97]],[[119861,119861],\\\"mapped\\\",[98]],[[119862,119862],\\\"mapped\\\",[99]],[[119863,119863],\\\"mapped\\\",[100]],[[119864,119864],\\\"mapped\\\",[101]],[[119865,119865],\\\"mapped\\\",[102]],[[119866,119866],\\\"mapped\\\",[103]],[[119867,119867],\\\"mapped\\\",[104]],[[119868,119868],\\\"mapped\\\",[105]],[[119869,119869],\\\"mapped\\\",[106]],[[119870,119870],\\\"mapped\\\",[107]],[[119871,119871],\\\"mapped\\\",[108]],[[119872,119872],\\\"mapped\\\",[109]],[[119873,119873],\\\"mapped\\\",[110]],[[119874,119874],\\\"mapped\\\",[111]],[[119875,119875],\\\"mapped\\\",[112]],[[119876,119876],\\\"mapped\\\",[113]],[[119877,119877],\\\"mapped\\\",[114]],[[119878,119878],\\\"mapped\\\",[115]],[[119879,119879],\\\"mapped\\\",[116]],[[119880,119880],\\\"mapped\\\",[117]],[[119881,119881],\\\"mapped\\\",[118]],[[119882,119882],\\\"mapped\\\",[119]],[[119883,119883],\\\"mapped\\\",[120]],[[119884,119884],\\\"mapped\\\",[121]],[[119885,119885],\\\"mapped\\\",[122]],[[119886,119886],\\\"mapped\\\",[97]],[[119887,119887],\\\"mapped\\\",[98]],[[119888,119888],\\\"mapped\\\",[99]],[[119889,119889],\\\"mapped\\\",[100]],[[119890,119890],\\\"mapped\\\",[101]],[[119891,119891],\\\"mapped\\\",[102]],[[119892,119892],\\\"mapped\\\",[103]],[[119893,119893],\\\"disallowed\\\"],[[119894,119894],\\\"mapped\\\",[105]],[[119895,119895],\\\"mapped\\\",[106]],[[119896,119896],\\\"mapped\\\",[107]],[[119897,119897],\\\"mapped\\\",[108]],[[119898,119898],\\\"mapped\\\",[109]],[[119899,119899],\\\"mapped\\\",[110]],[[119900,119900],\\\"mapped\\\",[111]],[[119901,119901],\\\"mapped\\\",[112]],[[119902,119902],\\\"mapped\\\",[113]],[[119903,119903],\\\"mapped\\\",[114]],[[119904,119904],\\\"mapped\\\",[115]],[[119905,119905],\\\"mapped\\\",[116]],[[119906,119906],\\\"mapped\\\",[117]],[[119907,119907],\\\"mapped\\\",[118]],[[119908,119908],\\\"mapped\\\",[119]],[[119909,119909],\\\"mapped\\\",[120]],[[119910,119910],\\\"mapped\\\",[121]],[[119911,119911],\\\"mapped\\\",[122]],[[119912,119912],\\\"mapped\\\",[97]],[[119913,119913],\\\"mapped\\\",[98]],[[119914,119914],\\\"mapped\\\",[99]],[[119915,119915],\\\"mapped\\\",[100]],[[119916,119916],\\\"mapped\\\",[101]],[[119917,119917],\\\"mapped\\\",[102]],[[119918,119918],\\\"mapped\\\",[103]],[[119919,119919],\\\"mapped\\\",[104]],[[119920,119920],\\\"mapped\\\",[105]],[[119921,119921],\\\"mapped\\\",[106]],[[119922,119922],\\\"mapped\\\",[107]],[[119923,119923],\\\"mapped\\\",[108]],[[119924,119924],\\\"mapped\\\",[109]],[[119925,119925],\\\"mapped\\\",[110]],[[119926,119926],\\\"mapped\\\",[111]],[[119927,119927],\\\"mapped\\\",[112]],[[119928,119928],\\\"mapped\\\",[113]],[[119929,119929],\\\"mapped\\\",[114]],[[119930,119930],\\\"mapped\\\",[115]],[[119931,119931],\\\"mapped\\\",[116]],[[119932,119932],\\\"mapped\\\",[117]],[[119933,119933],\\\"mapped\\\",[118]],[[119934,119934],\\\"mapped\\\",[119]],[[119935,119935],\\\"mapped\\\",[120]],[[119936,119936],\\\"mapped\\\",[121]],[[119937,119937],\\\"mapped\\\",[122]],[[119938,119938],\\\"mapped\\\",[97]],[[119939,119939],\\\"mapped\\\",[98]],[[119940,119940],\\\"mapped\\\",[99]],[[119941,119941],\\\"mapped\\\",[100]],[[119942,119942],\\\"mapped\\\",[101]],[[119943,119943],\\\"mapped\\\",[102]],[[119944,119944],\\\"mapped\\\",[103]],[[119945,119945],\\\"mapped\\\",[104]],[[119946,119946],\\\"mapped\\\",[105]],[[119947,119947],\\\"mapped\\\",[106]],[[119948,119948],\\\"mapped\\\",[107]],[[119949,119949],\\\"mapped\\\",[108]],[[119950,119950],\\\"mapped\\\",[109]],[[119951,119951],\\\"mapped\\\",[110]],[[119952,119952],\\\"mapped\\\",[111]],[[119953,119953],\\\"mapped\\\",[112]],[[119954,119954],\\\"mapped\\\",[113]],[[119955,119955],\\\"mapped\\\",[114]],[[119956,119956],\\\"mapped\\\",[115]],[[119957,119957],\\\"mapped\\\",[116]],[[119958,119958],\\\"mapped\\\",[117]],[[119959,119959],\\\"mapped\\\",[118]],[[119960,119960],\\\"mapped\\\",[119]],[[119961,119961],\\\"mapped\\\",[120]],[[119962,119962],\\\"mapped\\\",[121]],[[119963,119963],\\\"mapped\\\",[122]],[[119964,119964],\\\"mapped\\\",[97]],[[119965,119965],\\\"disallowed\\\"],[[119966,119966],\\\"mapped\\\",[99]],[[119967,119967],\\\"mapped\\\",[100]],[[119968,119969],\\\"disallowed\\\"],[[119970,119970],\\\"mapped\\\",[103]],[[119971,119972],\\\"disallowed\\\"],[[119973,119973],\\\"mapped\\\",[106]],[[119974,119974],\\\"mapped\\\",[107]],[[119975,119976],\\\"disallowed\\\"],[[119977,119977],\\\"mapped\\\",[110]],[[119978,119978],\\\"mapped\\\",[111]],[[119979,119979],\\\"mapped\\\",[112]],[[119980,119980],\\\"mapped\\\",[113]],[[119981,119981],\\\"disallowed\\\"],[[119982,119982],\\\"mapped\\\",[115]],[[119983,119983],\\\"mapped\\\",[116]],[[119984,119984],\\\"mapped\\\",[117]],[[119985,119985],\\\"mapped\\\",[118]],[[119986,119986],\\\"mapped\\\",[119]],[[119987,119987],\\\"mapped\\\",[120]],[[119988,119988],\\\"mapped\\\",[121]],[[119989,119989],\\\"mapped\\\",[122]],[[119990,119990],\\\"mapped\\\",[97]],[[119991,119991],\\\"mapped\\\",[98]],[[119992,119992],\\\"mapped\\\",[99]],[[119993,119993],\\\"mapped\\\",[100]],[[119994,119994],\\\"disallowed\\\"],[[119995,119995],\\\"mapped\\\",[102]],[[119996,119996],\\\"disallowed\\\"],[[119997,119997],\\\"mapped\\\",[104]],[[119998,119998],\\\"mapped\\\",[105]],[[119999,119999],\\\"mapped\\\",[106]],[[120000,120000],\\\"mapped\\\",[107]],[[120001,120001],\\\"mapped\\\",[108]],[[120002,120002],\\\"mapped\\\",[109]],[[120003,120003],\\\"mapped\\\",[110]],[[120004,120004],\\\"disallowed\\\"],[[120005,120005],\\\"mapped\\\",[112]],[[120006,120006],\\\"mapped\\\",[113]],[[120007,120007],\\\"mapped\\\",[114]],[[120008,120008],\\\"mapped\\\",[115]],[[120009,120009],\\\"mapped\\\",[116]],[[120010,120010],\\\"mapped\\\",[117]],[[120011,120011],\\\"mapped\\\",[118]],[[120012,120012],\\\"mapped\\\",[119]],[[120013,120013],\\\"mapped\\\",[120]],[[120014,120014],\\\"mapped\\\",[121]],[[120015,120015],\\\"mapped\\\",[122]],[[120016,120016],\\\"mapped\\\",[97]],[[120017,120017],\\\"mapped\\\",[98]],[[120018,120018],\\\"mapped\\\",[99]],[[120019,120019],\\\"mapped\\\",[100]],[[120020,120020],\\\"mapped\\\",[101]],[[120021,120021],\\\"mapped\\\",[102]],[[120022,120022],\\\"mapped\\\",[103]],[[120023,120023],\\\"mapped\\\",[104]],[[120024,120024],\\\"mapped\\\",[105]],[[120025,120025],\\\"mapped\\\",[106]],[[120026,120026],\\\"mapped\\\",[107]],[[120027,120027],\\\"mapped\\\",[108]],[[120028,120028],\\\"mapped\\\",[109]],[[120029,120029],\\\"mapped\\\",[110]],[[120030,120030],\\\"mapped\\\",[111]],[[120031,120031],\\\"mapped\\\",[112]],[[120032,120032],\\\"mapped\\\",[113]],[[120033,120033],\\\"mapped\\\",[114]],[[120034,120034],\\\"mapped\\\",[115]],[[120035,120035],\\\"mapped\\\",[116]],[[120036,120036],\\\"mapped\\\",[117]],[[120037,120037],\\\"mapped\\\",[118]],[[120038,120038],\\\"mapped\\\",[119]],[[120039,120039],\\\"mapped\\\",[120]],[[120040,120040],\\\"mapped\\\",[121]],[[120041,120041],\\\"mapped\\\",[122]],[[120042,120042],\\\"mapped\\\",[97]],[[120043,120043],\\\"mapped\\\",[98]],[[120044,120044],\\\"mapped\\\",[99]],[[120045,120045],\\\"mapped\\\",[100]],[[120046,120046],\\\"mapped\\\",[101]],[[120047,120047],\\\"mapped\\\",[102]],[[120048,120048],\\\"mapped\\\",[103]],[[120049,120049],\\\"mapped\\\",[104]],[[120050,120050],\\\"mapped\\\",[105]],[[120051,120051],\\\"mapped\\\",[106]],[[120052,120052],\\\"mapped\\\",[107]],[[120053,120053],\\\"mapped\\\",[108]],[[120054,120054],\\\"mapped\\\",[109]],[[120055,120055],\\\"mapped\\\",[110]],[[120056,120056],\\\"mapped\\\",[111]],[[120057,120057],\\\"mapped\\\",[112]],[[120058,120058],\\\"mapped\\\",[113]],[[120059,120059],\\\"mapped\\\",[114]],[[120060,120060],\\\"mapped\\\",[115]],[[120061,120061],\\\"mapped\\\",[116]],[[120062,120062],\\\"mapped\\\",[117]],[[120063,120063],\\\"mapped\\\",[118]],[[120064,120064],\\\"mapped\\\",[119]],[[120065,120065],\\\"mapped\\\",[120]],[[120066,120066],\\\"mapped\\\",[121]],[[120067,120067],\\\"mapped\\\",[122]],[[120068,120068],\\\"mapped\\\",[97]],[[120069,120069],\\\"mapped\\\",[98]],[[120070,120070],\\\"disallowed\\\"],[[120071,120071],\\\"mapped\\\",[100]],[[120072,120072],\\\"mapped\\\",[101]],[[120073,120073],\\\"mapped\\\",[102]],[[120074,120074],\\\"mapped\\\",[103]],[[120075,120076],\\\"disallowed\\\"],[[120077,120077],\\\"mapped\\\",[106]],[[120078,120078],\\\"mapped\\\",[107]],[[120079,120079],\\\"mapped\\\",[108]],[[120080,120080],\\\"mapped\\\",[109]],[[120081,120081],\\\"mapped\\\",[110]],[[120082,120082],\\\"mapped\\\",[111]],[[120083,120083],\\\"mapped\\\",[112]],[[120084,120084],\\\"mapped\\\",[113]],[[120085,120085],\\\"disallowed\\\"],[[120086,120086],\\\"mapped\\\",[115]],[[120087,120087],\\\"mapped\\\",[116]],[[120088,120088],\\\"mapped\\\",[117]],[[120089,120089],\\\"mapped\\\",[118]],[[120090,120090],\\\"mapped\\\",[119]],[[120091,120091],\\\"mapped\\\",[120]],[[120092,120092],\\\"mapped\\\",[121]],[[120093,120093],\\\"disallowed\\\"],[[120094,120094],\\\"mapped\\\",[97]],[[120095,120095],\\\"mapped\\\",[98]],[[120096,120096],\\\"mapped\\\",[99]],[[120097,120097],\\\"mapped\\\",[100]],[[120098,120098],\\\"mapped\\\",[101]],[[120099,120099],\\\"mapped\\\",[102]],[[120100,120100],\\\"mapped\\\",[103]],[[120101,120101],\\\"mapped\\\",[104]],[[120102,120102],\\\"mapped\\\",[105]],[[120103,120103],\\\"mapped\\\",[106]],[[120104,120104],\\\"mapped\\\",[107]],[[120105,120105],\\\"mapped\\\",[108]],[[120106,120106],\\\"mapped\\\",[109]],[[120107,120107],\\\"mapped\\\",[110]],[[120108,120108],\\\"mapped\\\",[111]],[[120109,120109],\\\"mapped\\\",[112]],[[120110,120110],\\\"mapped\\\",[113]],[[120111,120111],\\\"mapped\\\",[114]],[[120112,120112],\\\"mapped\\\",[115]],[[120113,120113],\\\"mapped\\\",[116]],[[120114,120114],\\\"mapped\\\",[117]],[[120115,120115],\\\"mapped\\\",[118]],[[120116,120116],\\\"mapped\\\",[119]],[[120117,120117],\\\"mapped\\\",[120]],[[120118,120118],\\\"mapped\\\",[121]],[[120119,120119],\\\"mapped\\\",[122]],[[120120,120120],\\\"mapped\\\",[97]],[[120121,120121],\\\"mapped\\\",[98]],[[120122,120122],\\\"disallowed\\\"],[[120123,120123],\\\"mapped\\\",[100]],[[120124,120124],\\\"mapped\\\",[101]],[[120125,120125],\\\"mapped\\\",[102]],[[120126,120126],\\\"mapped\\\",[103]],[[120127,120127],\\\"disallowed\\\"],[[120128,120128],\\\"mapped\\\",[105]],[[120129,120129],\\\"mapped\\\",[106]],[[120130,120130],\\\"mapped\\\",[107]],[[120131,120131],\\\"mapped\\\",[108]],[[120132,120132],\\\"mapped\\\",[109]],[[120133,120133],\\\"disallowed\\\"],[[120134,120134],\\\"mapped\\\",[111]],[[120135,120137],\\\"disallowed\\\"],[[120138,120138],\\\"mapped\\\",[115]],[[120139,120139],\\\"mapped\\\",[116]],[[120140,120140],\\\"mapped\\\",[117]],[[120141,120141],\\\"mapped\\\",[118]],[[120142,120142],\\\"mapped\\\",[119]],[[120143,120143],\\\"mapped\\\",[120]],[[120144,120144],\\\"mapped\\\",[121]],[[120145,120145],\\\"disallowed\\\"],[[120146,120146],\\\"mapped\\\",[97]],[[120147,120147],\\\"mapped\\\",[98]],[[120148,120148],\\\"mapped\\\",[99]],[[120149,120149],\\\"mapped\\\",[100]],[[120150,120150],\\\"mapped\\\",[101]],[[120151,120151],\\\"mapped\\\",[102]],[[120152,120152],\\\"mapped\\\",[103]],[[120153,120153],\\\"mapped\\\",[104]],[[120154,120154],\\\"mapped\\\",[105]],[[120155,120155],\\\"mapped\\\",[106]],[[120156,120156],\\\"mapped\\\",[107]],[[120157,120157],\\\"mapped\\\",[108]],[[120158,120158],\\\"mapped\\\",[109]],[[120159,120159],\\\"mapped\\\",[110]],[[120160,120160],\\\"mapped\\\",[111]],[[120161,120161],\\\"mapped\\\",[112]],[[120162,120162],\\\"mapped\\\",[113]],[[120163,120163],\\\"mapped\\\",[114]],[[120164,120164],\\\"mapped\\\",[115]],[[120165,120165],\\\"mapped\\\",[116]],[[120166,120166],\\\"mapped\\\",[117]],[[120167,120167],\\\"mapped\\\",[118]],[[120168,120168],\\\"mapped\\\",[119]],[[120169,120169],\\\"mapped\\\",[120]],[[120170,120170],\\\"mapped\\\",[121]],[[120171,120171],\\\"mapped\\\",[122]],[[120172,120172],\\\"mapped\\\",[97]],[[120173,120173],\\\"mapped\\\",[98]],[[120174,120174],\\\"mapped\\\",[99]],[[120175,120175],\\\"mapped\\\",[100]],[[120176,120176],\\\"mapped\\\",[101]],[[120177,120177],\\\"mapped\\\",[102]],[[120178,120178],\\\"mapped\\\",[103]],[[120179,120179],\\\"mapped\\\",[104]],[[120180,120180],\\\"mapped\\\",[105]],[[120181,120181],\\\"mapped\\\",[106]],[[120182,120182],\\\"mapped\\\",[107]],[[120183,120183],\\\"mapped\\\",[108]],[[120184,120184],\\\"mapped\\\",[109]],[[120185,120185],\\\"mapped\\\",[110]],[[120186,120186],\\\"mapped\\\",[111]],[[120187,120187],\\\"mapped\\\",[112]],[[120188,120188],\\\"mapped\\\",[113]],[[120189,120189],\\\"mapped\\\",[114]],[[120190,120190],\\\"mapped\\\",[115]],[[120191,120191],\\\"mapped\\\",[116]],[[120192,120192],\\\"mapped\\\",[117]],[[120193,120193],\\\"mapped\\\",[118]],[[120194,120194],\\\"mapped\\\",[119]],[[120195,120195],\\\"mapped\\\",[120]],[[120196,120196],\\\"mapped\\\",[121]],[[120197,120197],\\\"mapped\\\",[122]],[[120198,120198],\\\"mapped\\\",[97]],[[120199,120199],\\\"mapped\\\",[98]],[[120200,120200],\\\"mapped\\\",[99]],[[120201,120201],\\\"mapped\\\",[100]],[[120202,120202],\\\"mapped\\\",[101]],[[120203,120203],\\\"mapped\\\",[102]],[[120204,120204],\\\"mapped\\\",[103]],[[120205,120205],\\\"mapped\\\",[104]],[[120206,120206],\\\"mapped\\\",[105]],[[120207,120207],\\\"mapped\\\",[106]],[[120208,120208],\\\"mapped\\\",[107]],[[120209,120209],\\\"mapped\\\",[108]],[[120210,120210],\\\"mapped\\\",[109]],[[120211,120211],\\\"mapped\\\",[110]],[[120212,120212],\\\"mapped\\\",[111]],[[120213,120213],\\\"mapped\\\",[112]],[[120214,120214],\\\"mapped\\\",[113]],[[120215,120215],\\\"mapped\\\",[114]],[[120216,120216],\\\"mapped\\\",[115]],[[120217,120217],\\\"mapped\\\",[116]],[[120218,120218],\\\"mapped\\\",[117]],[[120219,120219],\\\"mapped\\\",[118]],[[120220,120220],\\\"mapped\\\",[119]],[[120221,120221],\\\"mapped\\\",[120]],[[120222,120222],\\\"mapped\\\",[121]],[[120223,120223],\\\"mapped\\\",[122]],[[120224,120224],\\\"mapped\\\",[97]],[[120225,120225],\\\"mapped\\\",[98]],[[120226,120226],\\\"mapped\\\",[99]],[[120227,120227],\\\"mapped\\\",[100]],[[120228,120228],\\\"mapped\\\",[101]],[[120229,120229],\\\"mapped\\\",[102]],[[120230,120230],\\\"mapped\\\",[103]],[[120231,120231],\\\"mapped\\\",[104]],[[120232,120232],\\\"mapped\\\",[105]],[[120233,120233],\\\"mapped\\\",[106]],[[120234,120234],\\\"mapped\\\",[107]],[[120235,120235],\\\"mapped\\\",[108]],[[120236,120236],\\\"mapped\\\",[109]],[[120237,120237],\\\"mapped\\\",[110]],[[120238,120238],\\\"mapped\\\",[111]],[[120239,120239],\\\"mapped\\\",[112]],[[120240,120240],\\\"mapped\\\",[113]],[[120241,120241],\\\"mapped\\\",[114]],[[120242,120242],\\\"mapped\\\",[115]],[[120243,120243],\\\"mapped\\\",[116]],[[120244,120244],\\\"mapped\\\",[117]],[[120245,120245],\\\"mapped\\\",[118]],[[120246,120246],\\\"mapped\\\",[119]],[[120247,120247],\\\"mapped\\\",[120]],[[120248,120248],\\\"mapped\\\",[121]],[[120249,120249],\\\"mapped\\\",[122]],[[120250,120250],\\\"mapped\\\",[97]],[[120251,120251],\\\"mapped\\\",[98]],[[120252,120252],\\\"mapped\\\",[99]],[[120253,120253],\\\"mapped\\\",[100]],[[120254,120254],\\\"mapped\\\",[101]],[[120255,120255],\\\"mapped\\\",[102]],[[120256,120256],\\\"mapped\\\",[103]],[[120257,120257],\\\"mapped\\\",[104]],[[120258,120258],\\\"mapped\\\",[105]],[[120259,120259],\\\"mapped\\\",[106]],[[120260,120260],\\\"mapped\\\",[107]],[[120261,120261],\\\"mapped\\\",[108]],[[120262,120262],\\\"mapped\\\",[109]],[[120263,120263],\\\"mapped\\\",[110]],[[120264,120264],\\\"mapped\\\",[111]],[[120265,120265],\\\"mapped\\\",[112]],[[120266,120266],\\\"mapped\\\",[113]],[[120267,120267],\\\"mapped\\\",[114]],[[120268,120268],\\\"mapped\\\",[115]],[[120269,120269],\\\"mapped\\\",[116]],[[120270,120270],\\\"mapped\\\",[117]],[[120271,120271],\\\"mapped\\\",[118]],[[120272,120272],\\\"mapped\\\",[119]],[[120273,120273],\\\"mapped\\\",[120]],[[120274,120274],\\\"mapped\\\",[121]],[[120275,120275],\\\"mapped\\\",[122]],[[120276,120276],\\\"mapped\\\",[97]],[[120277,120277],\\\"mapped\\\",[98]],[[120278,120278],\\\"mapped\\\",[99]],[[120279,120279],\\\"mapped\\\",[100]],[[120280,120280],\\\"mapped\\\",[101]],[[120281,120281],\\\"mapped\\\",[102]],[[120282,120282],\\\"mapped\\\",[103]],[[120283,120283],\\\"mapped\\\",[104]],[[120284,120284],\\\"mapped\\\",[105]],[[120285,120285],\\\"mapped\\\",[106]],[[120286,120286],\\\"mapped\\\",[107]],[[120287,120287],\\\"mapped\\\",[108]],[[120288,120288],\\\"mapped\\\",[109]],[[120289,120289],\\\"mapped\\\",[110]],[[120290,120290],\\\"mapped\\\",[111]],[[120291,120291],\\\"mapped\\\",[112]],[[120292,120292],\\\"mapped\\\",[113]],[[120293,120293],\\\"mapped\\\",[114]],[[120294,120294],\\\"mapped\\\",[115]],[[120295,120295],\\\"mapped\\\",[116]],[[120296,120296],\\\"mapped\\\",[117]],[[120297,120297],\\\"mapped\\\",[118]],[[120298,120298],\\\"mapped\\\",[119]],[[120299,120299],\\\"mapped\\\",[120]],[[120300,120300],\\\"mapped\\\",[121]],[[120301,120301],\\\"mapped\\\",[122]],[[120302,120302],\\\"mapped\\\",[97]],[[120303,120303],\\\"mapped\\\",[98]],[[120304,120304],\\\"mapped\\\",[99]],[[120305,120305],\\\"mapped\\\",[100]],[[120306,120306],\\\"mapped\\\",[101]],[[120307,120307],\\\"mapped\\\",[102]],[[120308,120308],\\\"mapped\\\",[103]],[[120309,120309],\\\"mapped\\\",[104]],[[120310,120310],\\\"mapped\\\",[105]],[[120311,120311],\\\"mapped\\\",[106]],[[120312,120312],\\\"mapped\\\",[107]],[[120313,120313],\\\"mapped\\\",[108]],[[120314,120314],\\\"mapped\\\",[109]],[[120315,120315],\\\"mapped\\\",[110]],[[120316,120316],\\\"mapped\\\",[111]],[[120317,120317],\\\"mapped\\\",[112]],[[120318,120318],\\\"mapped\\\",[113]],[[120319,120319],\\\"mapped\\\",[114]],[[120320,120320],\\\"mapped\\\",[115]],[[120321,120321],\\\"mapped\\\",[116]],[[120322,120322],\\\"mapped\\\",[117]],[[120323,120323],\\\"mapped\\\",[118]],[[120324,120324],\\\"mapped\\\",[119]],[[120325,120325],\\\"mapped\\\",[120]],[[120326,120326],\\\"mapped\\\",[121]],[[120327,120327],\\\"mapped\\\",[122]],[[120328,120328],\\\"mapped\\\",[97]],[[120329,120329],\\\"mapped\\\",[98]],[[120330,120330],\\\"mapped\\\",[99]],[[120331,120331],\\\"mapped\\\",[100]],[[120332,120332],\\\"mapped\\\",[101]],[[120333,120333],\\\"mapped\\\",[102]],[[120334,120334],\\\"mapped\\\",[103]],[[120335,120335],\\\"mapped\\\",[104]],[[120336,120336],\\\"mapped\\\",[105]],[[120337,120337],\\\"mapped\\\",[106]],[[120338,120338],\\\"mapped\\\",[107]],[[120339,120339],\\\"mapped\\\",[108]],[[120340,120340],\\\"mapped\\\",[109]],[[120341,120341],\\\"mapped\\\",[110]],[[120342,120342],\\\"mapped\\\",[111]],[[120343,120343],\\\"mapped\\\",[112]],[[120344,120344],\\\"mapped\\\",[113]],[[120345,120345],\\\"mapped\\\",[114]],[[120346,120346],\\\"mapped\\\",[115]],[[120347,120347],\\\"mapped\\\",[116]],[[120348,120348],\\\"mapped\\\",[117]],[[120349,120349],\\\"mapped\\\",[118]],[[120350,120350],\\\"mapped\\\",[119]],[[120351,120351],\\\"mapped\\\",[120]],[[120352,120352],\\\"mapped\\\",[121]],[[120353,120353],\\\"mapped\\\",[122]],[[120354,120354],\\\"mapped\\\",[97]],[[120355,120355],\\\"mapped\\\",[98]],[[120356,120356],\\\"mapped\\\",[99]],[[120357,120357],\\\"mapped\\\",[100]],[[120358,120358],\\\"mapped\\\",[101]],[[120359,120359],\\\"mapped\\\",[102]],[[120360,120360],\\\"mapped\\\",[103]],[[120361,120361],\\\"mapped\\\",[104]],[[120362,120362],\\\"mapped\\\",[105]],[[120363,120363],\\\"mapped\\\",[106]],[[120364,120364],\\\"mapped\\\",[107]],[[120365,120365],\\\"mapped\\\",[108]],[[120366,120366],\\\"mapped\\\",[109]],[[120367,120367],\\\"mapped\\\",[110]],[[120368,120368],\\\"mapped\\\",[111]],[[120369,120369],\\\"mapped\\\",[112]],[[120370,120370],\\\"mapped\\\",[113]],[[120371,120371],\\\"mapped\\\",[114]],[[120372,120372],\\\"mapped\\\",[115]],[[120373,120373],\\\"mapped\\\",[116]],[[120374,120374],\\\"mapped\\\",[117]],[[120375,120375],\\\"mapped\\\",[118]],[[120376,120376],\\\"mapped\\\",[119]],[[120377,120377],\\\"mapped\\\",[120]],[[120378,120378],\\\"mapped\\\",[121]],[[120379,120379],\\\"mapped\\\",[122]],[[120380,120380],\\\"mapped\\\",[97]],[[120381,120381],\\\"mapped\\\",[98]],[[120382,120382],\\\"mapped\\\",[99]],[[120383,120383],\\\"mapped\\\",[100]],[[120384,120384],\\\"mapped\\\",[101]],[[120385,120385],\\\"mapped\\\",[102]],[[120386,120386],\\\"mapped\\\",[103]],[[120387,120387],\\\"mapped\\\",[104]],[[120388,120388],\\\"mapped\\\",[105]],[[120389,120389],\\\"mapped\\\",[106]],[[120390,120390],\\\"mapped\\\",[107]],[[120391,120391],\\\"mapped\\\",[108]],[[120392,120392],\\\"mapped\\\",[109]],[[120393,120393],\\\"mapped\\\",[110]],[[120394,120394],\\\"mapped\\\",[111]],[[120395,120395],\\\"mapped\\\",[112]],[[120396,120396],\\\"mapped\\\",[113]],[[120397,120397],\\\"mapped\\\",[114]],[[120398,120398],\\\"mapped\\\",[115]],[[120399,120399],\\\"mapped\\\",[116]],[[120400,120400],\\\"mapped\\\",[117]],[[120401,120401],\\\"mapped\\\",[118]],[[120402,120402],\\\"mapped\\\",[119]],[[120403,120403],\\\"mapped\\\",[120]],[[120404,120404],\\\"mapped\\\",[121]],[[120405,120405],\\\"mapped\\\",[122]],[[120406,120406],\\\"mapped\\\",[97]],[[120407,120407],\\\"mapped\\\",[98]],[[120408,120408],\\\"mapped\\\",[99]],[[120409,120409],\\\"mapped\\\",[100]],[[120410,120410],\\\"mapped\\\",[101]],[[120411,120411],\\\"mapped\\\",[102]],[[120412,120412],\\\"mapped\\\",[103]],[[120413,120413],\\\"mapped\\\",[104]],[[120414,120414],\\\"mapped\\\",[105]],[[120415,120415],\\\"mapped\\\",[106]],[[120416,120416],\\\"mapped\\\",[107]],[[120417,120417],\\\"mapped\\\",[108]],[[120418,120418],\\\"mapped\\\",[109]],[[120419,120419],\\\"mapped\\\",[110]],[[120420,120420],\\\"mapped\\\",[111]],[[120421,120421],\\\"mapped\\\",[112]],[[120422,120422],\\\"mapped\\\",[113]],[[120423,120423],\\\"mapped\\\",[114]],[[120424,120424],\\\"mapped\\\",[115]],[[120425,120425],\\\"mapped\\\",[116]],[[120426,120426],\\\"mapped\\\",[117]],[[120427,120427],\\\"mapped\\\",[118]],[[120428,120428],\\\"mapped\\\",[119]],[[120429,120429],\\\"mapped\\\",[120]],[[120430,120430],\\\"mapped\\\",[121]],[[120431,120431],\\\"mapped\\\",[122]],[[120432,120432],\\\"mapped\\\",[97]],[[120433,120433],\\\"mapped\\\",[98]],[[120434,120434],\\\"mapped\\\",[99]],[[120435,120435],\\\"mapped\\\",[100]],[[120436,120436],\\\"mapped\\\",[101]],[[120437,120437],\\\"mapped\\\",[102]],[[120438,120438],\\\"mapped\\\",[103]],[[120439,120439],\\\"mapped\\\",[104]],[[120440,120440],\\\"mapped\\\",[105]],[[120441,120441],\\\"mapped\\\",[106]],[[120442,120442],\\\"mapped\\\",[107]],[[120443,120443],\\\"mapped\\\",[108]],[[120444,120444],\\\"mapped\\\",[109]],[[120445,120445],\\\"mapped\\\",[110]],[[120446,120446],\\\"mapped\\\",[111]],[[120447,120447],\\\"mapped\\\",[112]],[[120448,120448],\\\"mapped\\\",[113]],[[120449,120449],\\\"mapped\\\",[114]],[[120450,120450],\\\"mapped\\\",[115]],[[120451,120451],\\\"mapped\\\",[116]],[[120452,120452],\\\"mapped\\\",[117]],[[120453,120453],\\\"mapped\\\",[118]],[[120454,120454],\\\"mapped\\\",[119]],[[120455,120455],\\\"mapped\\\",[120]],[[120456,120456],\\\"mapped\\\",[121]],[[120457,120457],\\\"mapped\\\",[122]],[[120458,120458],\\\"mapped\\\",[97]],[[120459,120459],\\\"mapped\\\",[98]],[[120460,120460],\\\"mapped\\\",[99]],[[120461,120461],\\\"mapped\\\",[100]],[[120462,120462],\\\"mapped\\\",[101]],[[120463,120463],\\\"mapped\\\",[102]],[[120464,120464],\\\"mapped\\\",[103]],[[120465,120465],\\\"mapped\\\",[104]],[[120466,120466],\\\"mapped\\\",[105]],[[120467,120467],\\\"mapped\\\",[106]],[[120468,120468],\\\"mapped\\\",[107]],[[120469,120469],\\\"mapped\\\",[108]],[[120470,120470],\\\"mapped\\\",[109]],[[120471,120471],\\\"mapped\\\",[110]],[[120472,120472],\\\"mapped\\\",[111]],[[120473,120473],\\\"mapped\\\",[112]],[[120474,120474],\\\"mapped\\\",[113]],[[120475,120475],\\\"mapped\\\",[114]],[[120476,120476],\\\"mapped\\\",[115]],[[120477,120477],\\\"mapped\\\",[116]],[[120478,120478],\\\"mapped\\\",[117]],[[120479,120479],\\\"mapped\\\",[118]],[[120480,120480],\\\"mapped\\\",[119]],[[120481,120481],\\\"mapped\\\",[120]],[[120482,120482],\\\"mapped\\\",[121]],[[120483,120483],\\\"mapped\\\",[122]],[[120484,120484],\\\"mapped\\\",[305]],[[120485,120485],\\\"mapped\\\",[567]],[[120486,120487],\\\"disallowed\\\"],[[120488,120488],\\\"mapped\\\",[945]],[[120489,120489],\\\"mapped\\\",[946]],[[120490,120490],\\\"mapped\\\",[947]],[[120491,120491],\\\"mapped\\\",[948]],[[120492,120492],\\\"mapped\\\",[949]],[[120493,120493],\\\"mapped\\\",[950]],[[120494,120494],\\\"mapped\\\",[951]],[[120495,120495],\\\"mapped\\\",[952]],[[120496,120496],\\\"mapped\\\",[953]],[[120497,120497],\\\"mapped\\\",[954]],[[120498,120498],\\\"mapped\\\",[955]],[[120499,120499],\\\"mapped\\\",[956]],[[120500,120500],\\\"mapped\\\",[957]],[[120501,120501],\\\"mapped\\\",[958]],[[120502,120502],\\\"mapped\\\",[959]],[[120503,120503],\\\"mapped\\\",[960]],[[120504,120504],\\\"mapped\\\",[961]],[[120505,120505],\\\"mapped\\\",[952]],[[120506,120506],\\\"mapped\\\",[963]],[[120507,120507],\\\"mapped\\\",[964]],[[120508,120508],\\\"mapped\\\",[965]],[[120509,120509],\\\"mapped\\\",[966]],[[120510,120510],\\\"mapped\\\",[967]],[[120511,120511],\\\"mapped\\\",[968]],[[120512,120512],\\\"mapped\\\",[969]],[[120513,120513],\\\"mapped\\\",[8711]],[[120514,120514],\\\"mapped\\\",[945]],[[120515,120515],\\\"mapped\\\",[946]],[[120516,120516],\\\"mapped\\\",[947]],[[120517,120517],\\\"mapped\\\",[948]],[[120518,120518],\\\"mapped\\\",[949]],[[120519,120519],\\\"mapped\\\",[950]],[[120520,120520],\\\"mapped\\\",[951]],[[120521,120521],\\\"mapped\\\",[952]],[[120522,120522],\\\"mapped\\\",[953]],[[120523,120523],\\\"mapped\\\",[954]],[[120524,120524],\\\"mapped\\\",[955]],[[120525,120525],\\\"mapped\\\",[956]],[[120526,120526],\\\"mapped\\\",[957]],[[120527,120527],\\\"mapped\\\",[958]],[[120528,120528],\\\"mapped\\\",[959]],[[120529,120529],\\\"mapped\\\",[960]],[[120530,120530],\\\"mapped\\\",[961]],[[120531,120532],\\\"mapped\\\",[963]],[[120533,120533],\\\"mapped\\\",[964]],[[120534,120534],\\\"mapped\\\",[965]],[[120535,120535],\\\"mapped\\\",[966]],[[120536,120536],\\\"mapped\\\",[967]],[[120537,120537],\\\"mapped\\\",[968]],[[120538,120538],\\\"mapped\\\",[969]],[[120539,120539],\\\"mapped\\\",[8706]],[[120540,120540],\\\"mapped\\\",[949]],[[120541,120541],\\\"mapped\\\",[952]],[[120542,120542],\\\"mapped\\\",[954]],[[120543,120543],\\\"mapped\\\",[966]],[[120544,120544],\\\"mapped\\\",[961]],[[120545,120545],\\\"mapped\\\",[960]],[[120546,120546],\\\"mapped\\\",[945]],[[120547,120547],\\\"mapped\\\",[946]],[[120548,120548],\\\"mapped\\\",[947]],[[120549,120549],\\\"mapped\\\",[948]],[[120550,120550],\\\"mapped\\\",[949]],[[120551,120551],\\\"mapped\\\",[950]],[[120552,120552],\\\"mapped\\\",[951]],[[120553,120553],\\\"mapped\\\",[952]],[[120554,120554],\\\"mapped\\\",[953]],[[120555,120555],\\\"mapped\\\",[954]],[[120556,120556],\\\"mapped\\\",[955]],[[120557,120557],\\\"mapped\\\",[956]],[[120558,120558],\\\"mapped\\\",[957]],[[120559,120559],\\\"mapped\\\",[958]],[[120560,120560],\\\"mapped\\\",[959]],[[120561,120561],\\\"mapped\\\",[960]],[[120562,120562],\\\"mapped\\\",[961]],[[120563,120563],\\\"mapped\\\",[952]],[[120564,120564],\\\"mapped\\\",[963]],[[120565,120565],\\\"mapped\\\",[964]],[[120566,120566],\\\"mapped\\\",[965]],[[120567,120567],\\\"mapped\\\",[966]],[[120568,120568],\\\"mapped\\\",[967]],[[120569,120569],\\\"mapped\\\",[968]],[[120570,120570],\\\"mapped\\\",[969]],[[120571,120571],\\\"mapped\\\",[8711]],[[120572,120572],\\\"mapped\\\",[945]],[[120573,120573],\\\"mapped\\\",[946]],[[120574,120574],\\\"mapped\\\",[947]],[[120575,120575],\\\"mapped\\\",[948]],[[120576,120576],\\\"mapped\\\",[949]],[[120577,120577],\\\"mapped\\\",[950]],[[120578,120578],\\\"mapped\\\",[951]],[[120579,120579],\\\"mapped\\\",[952]],[[120580,120580],\\\"mapped\\\",[953]],[[120581,120581],\\\"mapped\\\",[954]],[[120582,120582],\\\"mapped\\\",[955]],[[120583,120583],\\\"mapped\\\",[956]],[[120584,120584],\\\"mapped\\\",[957]],[[120585,120585],\\\"mapped\\\",[958]],[[120586,120586],\\\"mapped\\\",[959]],[[120587,120587],\\\"mapped\\\",[960]],[[120588,120588],\\\"mapped\\\",[961]],[[120589,120590],\\\"mapped\\\",[963]],[[120591,120591],\\\"mapped\\\",[964]],[[120592,120592],\\\"mapped\\\",[965]],[[120593,120593],\\\"mapped\\\",[966]],[[120594,120594],\\\"mapped\\\",[967]],[[120595,120595],\\\"mapped\\\",[968]],[[120596,120596],\\\"mapped\\\",[969]],[[120597,120597],\\\"mapped\\\",[8706]],[[120598,120598],\\\"mapped\\\",[949]],[[120599,120599],\\\"mapped\\\",[952]],[[120600,120600],\\\"mapped\\\",[954]],[[120601,120601],\\\"mapped\\\",[966]],[[120602,120602],\\\"mapped\\\",[961]],[[120603,120603],\\\"mapped\\\",[960]],[[120604,120604],\\\"mapped\\\",[945]],[[120605,120605],\\\"mapped\\\",[946]],[[120606,120606],\\\"mapped\\\",[947]],[[120607,120607],\\\"mapped\\\",[948]],[[120608,120608],\\\"mapped\\\",[949]],[[120609,120609],\\\"mapped\\\",[950]],[[120610,120610],\\\"mapped\\\",[951]],[[120611,120611],\\\"mapped\\\",[952]],[[120612,120612],\\\"mapped\\\",[953]],[[120613,120613],\\\"mapped\\\",[954]],[[120614,120614],\\\"mapped\\\",[955]],[[120615,120615],\\\"mapped\\\",[956]],[[120616,120616],\\\"mapped\\\",[957]],[[120617,120617],\\\"mapped\\\",[958]],[[120618,120618],\\\"mapped\\\",[959]],[[120619,120619],\\\"mapped\\\",[960]],[[120620,120620],\\\"mapped\\\",[961]],[[120621,120621],\\\"mapped\\\",[952]],[[120622,120622],\\\"mapped\\\",[963]],[[120623,120623],\\\"mapped\\\",[964]],[[120624,120624],\\\"mapped\\\",[965]],[[120625,120625],\\\"mapped\\\",[966]],[[120626,120626],\\\"mapped\\\",[967]],[[120627,120627],\\\"mapped\\\",[968]],[[120628,120628],\\\"mapped\\\",[969]],[[120629,120629],\\\"mapped\\\",[8711]],[[120630,120630],\\\"mapped\\\",[945]],[[120631,120631],\\\"mapped\\\",[946]],[[120632,120632],\\\"mapped\\\",[947]],[[120633,120633],\\\"mapped\\\",[948]],[[120634,120634],\\\"mapped\\\",[949]],[[120635,120635],\\\"mapped\\\",[950]],[[120636,120636],\\\"mapped\\\",[951]],[[120637,120637],\\\"mapped\\\",[952]],[[120638,120638],\\\"mapped\\\",[953]],[[120639,120639],\\\"mapped\\\",[954]],[[120640,120640],\\\"mapped\\\",[955]],[[120641,120641],\\\"mapped\\\",[956]],[[120642,120642],\\\"mapped\\\",[957]],[[120643,120643],\\\"mapped\\\",[958]],[[120644,120644],\\\"mapped\\\",[959]],[[120645,120645],\\\"mapped\\\",[960]],[[120646,120646],\\\"mapped\\\",[961]],[[120647,120648],\\\"mapped\\\",[963]],[[120649,120649],\\\"mapped\\\",[964]],[[120650,120650],\\\"mapped\\\",[965]],[[120651,120651],\\\"mapped\\\",[966]],[[120652,120652],\\\"mapped\\\",[967]],[[120653,120653],\\\"mapped\\\",[968]],[[120654,120654],\\\"mapped\\\",[969]],[[120655,120655],\\\"mapped\\\",[8706]],[[120656,120656],\\\"mapped\\\",[949]],[[120657,120657],\\\"mapped\\\",[952]],[[120658,120658],\\\"mapped\\\",[954]],[[120659,120659],\\\"mapped\\\",[966]],[[120660,120660],\\\"mapped\\\",[961]],[[120661,120661],\\\"mapped\\\",[960]],[[120662,120662],\\\"mapped\\\",[945]],[[120663,120663],\\\"mapped\\\",[946]],[[120664,120664],\\\"mapped\\\",[947]],[[120665,120665],\\\"mapped\\\",[948]],[[120666,120666],\\\"mapped\\\",[949]],[[120667,120667],\\\"mapped\\\",[950]],[[120668,120668],\\\"mapped\\\",[951]],[[120669,120669],\\\"mapped\\\",[952]],[[120670,120670],\\\"mapped\\\",[953]],[[120671,120671],\\\"mapped\\\",[954]],[[120672,120672],\\\"mapped\\\",[955]],[[120673,120673],\\\"mapped\\\",[956]],[[120674,120674],\\\"mapped\\\",[957]],[[120675,120675],\\\"mapped\\\",[958]],[[120676,120676],\\\"mapped\\\",[959]],[[120677,120677],\\\"mapped\\\",[960]],[[120678,120678],\\\"mapped\\\",[961]],[[120679,120679],\\\"mapped\\\",[952]],[[120680,120680],\\\"mapped\\\",[963]],[[120681,120681],\\\"mapped\\\",[964]],[[120682,120682],\\\"mapped\\\",[965]],[[120683,120683],\\\"mapped\\\",[966]],[[120684,120684],\\\"mapped\\\",[967]],[[120685,120685],\\\"mapped\\\",[968]],[[120686,120686],\\\"mapped\\\",[969]],[[120687,120687],\\\"mapped\\\",[8711]],[[120688,120688],\\\"mapped\\\",[945]],[[120689,120689],\\\"mapped\\\",[946]],[[120690,120690],\\\"mapped\\\",[947]],[[120691,120691],\\\"mapped\\\",[948]],[[120692,120692],\\\"mapped\\\",[949]],[[120693,120693],\\\"mapped\\\",[950]],[[120694,120694],\\\"mapped\\\",[951]],[[120695,120695],\\\"mapped\\\",[952]],[[120696,120696],\\\"mapped\\\",[953]],[[120697,120697],\\\"mapped\\\",[954]],[[120698,120698],\\\"mapped\\\",[955]],[[120699,120699],\\\"mapped\\\",[956]],[[120700,120700],\\\"mapped\\\",[957]],[[120701,120701],\\\"mapped\\\",[958]],[[120702,120702],\\\"mapped\\\",[959]],[[120703,120703],\\\"mapped\\\",[960]],[[120704,120704],\\\"mapped\\\",[961]],[[120705,120706],\\\"mapped\\\",[963]],[[120707,120707],\\\"mapped\\\",[964]],[[120708,120708],\\\"mapped\\\",[965]],[[120709,120709],\\\"mapped\\\",[966]],[[120710,120710],\\\"mapped\\\",[967]],[[120711,120711],\\\"mapped\\\",[968]],[[120712,120712],\\\"mapped\\\",[969]],[[120713,120713],\\\"mapped\\\",[8706]],[[120714,120714],\\\"mapped\\\",[949]],[[120715,120715],\\\"mapped\\\",[952]],[[120716,120716],\\\"mapped\\\",[954]],[[120717,120717],\\\"mapped\\\",[966]],[[120718,120718],\\\"mapped\\\",[961]],[[120719,120719],\\\"mapped\\\",[960]],[[120720,120720],\\\"mapped\\\",[945]],[[120721,120721],\\\"mapped\\\",[946]],[[120722,120722],\\\"mapped\\\",[947]],[[120723,120723],\\\"mapped\\\",[948]],[[120724,120724],\\\"mapped\\\",[949]],[[120725,120725],\\\"mapped\\\",[950]],[[120726,120726],\\\"mapped\\\",[951]],[[120727,120727],\\\"mapped\\\",[952]],[[120728,120728],\\\"mapped\\\",[953]],[[120729,120729],\\\"mapped\\\",[954]],[[120730,120730],\\\"mapped\\\",[955]],[[120731,120731],\\\"mapped\\\",[956]],[[120732,120732],\\\"mapped\\\",[957]],[[120733,120733],\\\"mapped\\\",[958]],[[120734,120734],\\\"mapped\\\",[959]],[[120735,120735],\\\"mapped\\\",[960]],[[120736,120736],\\\"mapped\\\",[961]],[[120737,120737],\\\"mapped\\\",[952]],[[120738,120738],\\\"mapped\\\",[963]],[[120739,120739],\\\"mapped\\\",[964]],[[120740,120740],\\\"mapped\\\",[965]],[[120741,120741],\\\"mapped\\\",[966]],[[120742,120742],\\\"mapped\\\",[967]],[[120743,120743],\\\"mapped\\\",[968]],[[120744,120744],\\\"mapped\\\",[969]],[[120745,120745],\\\"mapped\\\",[8711]],[[120746,120746],\\\"mapped\\\",[945]],[[120747,120747],\\\"mapped\\\",[946]],[[120748,120748],\\\"mapped\\\",[947]],[[120749,120749],\\\"mapped\\\",[948]],[[120750,120750],\\\"mapped\\\",[949]],[[120751,120751],\\\"mapped\\\",[950]],[[120752,120752],\\\"mapped\\\",[951]],[[120753,120753],\\\"mapped\\\",[952]],[[120754,120754],\\\"mapped\\\",[953]],[[120755,120755],\\\"mapped\\\",[954]],[[120756,120756],\\\"mapped\\\",[955]],[[120757,120757],\\\"mapped\\\",[956]],[[120758,120758],\\\"mapped\\\",[957]],[[120759,120759],\\\"mapped\\\",[958]],[[120760,120760],\\\"mapped\\\",[959]],[[120761,120761],\\\"mapped\\\",[960]],[[120762,120762],\\\"mapped\\\",[961]],[[120763,120764],\\\"mapped\\\",[963]],[[120765,120765],\\\"mapped\\\",[964]],[[120766,120766],\\\"mapped\\\",[965]],[[120767,120767],\\\"mapped\\\",[966]],[[120768,120768],\\\"mapped\\\",[967]],[[120769,120769],\\\"mapped\\\",[968]],[[120770,120770],\\\"mapped\\\",[969]],[[120771,120771],\\\"mapped\\\",[8706]],[[120772,120772],\\\"mapped\\\",[949]],[[120773,120773],\\\"mapped\\\",[952]],[[120774,120774],\\\"mapped\\\",[954]],[[120775,120775],\\\"mapped\\\",[966]],[[120776,120776],\\\"mapped\\\",[961]],[[120777,120777],\\\"mapped\\\",[960]],[[120778,120779],\\\"mapped\\\",[989]],[[120780,120781],\\\"disallowed\\\"],[[120782,120782],\\\"mapped\\\",[48]],[[120783,120783],\\\"mapped\\\",[49]],[[120784,120784],\\\"mapped\\\",[50]],[[120785,120785],\\\"mapped\\\",[51]],[[120786,120786],\\\"mapped\\\",[52]],[[120787,120787],\\\"mapped\\\",[53]],[[120788,120788],\\\"mapped\\\",[54]],[[120789,120789],\\\"mapped\\\",[55]],[[120790,120790],\\\"mapped\\\",[56]],[[120791,120791],\\\"mapped\\\",[57]],[[120792,120792],\\\"mapped\\\",[48]],[[120793,120793],\\\"mapped\\\",[49]],[[120794,120794],\\\"mapped\\\",[50]],[[120795,120795],\\\"mapped\\\",[51]],[[120796,120796],\\\"mapped\\\",[52]],[[120797,120797],\\\"mapped\\\",[53]],[[120798,120798],\\\"mapped\\\",[54]],[[120799,120799],\\\"mapped\\\",[55]],[[120800,120800],\\\"mapped\\\",[56]],[[120801,120801],\\\"mapped\\\",[57]],[[120802,120802],\\\"mapped\\\",[48]],[[120803,120803],\\\"mapped\\\",[49]],[[120804,120804],\\\"mapped\\\",[50]],[[120805,120805],\\\"mapped\\\",[51]],[[120806,120806],\\\"mapped\\\",[52]],[[120807,120807],\\\"mapped\\\",[53]],[[120808,120808],\\\"mapped\\\",[54]],[[120809,120809],\\\"mapped\\\",[55]],[[120810,120810],\\\"mapped\\\",[56]],[[120811,120811],\\\"mapped\\\",[57]],[[120812,120812],\\\"mapped\\\",[48]],[[120813,120813],\\\"mapped\\\",[49]],[[120814,120814],\\\"mapped\\\",[50]],[[120815,120815],\\\"mapped\\\",[51]],[[120816,120816],\\\"mapped\\\",[52]],[[120817,120817],\\\"mapped\\\",[53]],[[120818,120818],\\\"mapped\\\",[54]],[[120819,120819],\\\"mapped\\\",[55]],[[120820,120820],\\\"mapped\\\",[56]],[[120821,120821],\\\"mapped\\\",[57]],[[120822,120822],\\\"mapped\\\",[48]],[[120823,120823],\\\"mapped\\\",[49]],[[120824,120824],\\\"mapped\\\",[50]],[[120825,120825],\\\"mapped\\\",[51]],[[120826,120826],\\\"mapped\\\",[52]],[[120827,120827],\\\"mapped\\\",[53]],[[120828,120828],\\\"mapped\\\",[54]],[[120829,120829],\\\"mapped\\\",[55]],[[120830,120830],\\\"mapped\\\",[56]],[[120831,120831],\\\"mapped\\\",[57]],[[120832,121343],\\\"valid\\\",[],\\\"NV8\\\"],[[121344,121398],\\\"valid\\\"],[[121399,121402],\\\"valid\\\",[],\\\"NV8\\\"],[[121403,121452],\\\"valid\\\"],[[121453,121460],\\\"valid\\\",[],\\\"NV8\\\"],[[121461,121461],\\\"valid\\\"],[[121462,121475],\\\"valid\\\",[],\\\"NV8\\\"],[[121476,121476],\\\"valid\\\"],[[121477,121483],\\\"valid\\\",[],\\\"NV8\\\"],[[121484,121498],\\\"disallowed\\\"],[[121499,121503],\\\"valid\\\"],[[121504,121504],\\\"disallowed\\\"],[[121505,121519],\\\"valid\\\"],[[121520,124927],\\\"disallowed\\\"],[[124928,125124],\\\"valid\\\"],[[125125,125126],\\\"disallowed\\\"],[[125127,125135],\\\"valid\\\",[],\\\"NV8\\\"],[[125136,125142],\\\"valid\\\"],[[125143,126463],\\\"disallowed\\\"],[[126464,126464],\\\"mapped\\\",[1575]],[[126465,126465],\\\"mapped\\\",[1576]],[[126466,126466],\\\"mapped\\\",[1580]],[[126467,126467],\\\"mapped\\\",[1583]],[[126468,126468],\\\"disallowed\\\"],[[126469,126469],\\\"mapped\\\",[1608]],[[126470,126470],\\\"mapped\\\",[1586]],[[126471,126471],\\\"mapped\\\",[1581]],[[126472,126472],\\\"mapped\\\",[1591]],[[126473,126473],\\\"mapped\\\",[1610]],[[126474,126474],\\\"mapped\\\",[1603]],[[126475,126475],\\\"mapped\\\",[1604]],[[126476,126476],\\\"mapped\\\",[1605]],[[126477,126477],\\\"mapped\\\",[1606]],[[126478,126478],\\\"mapped\\\",[1587]],[[126479,126479],\\\"mapped\\\",[1593]],[[126480,126480],\\\"mapped\\\",[1601]],[[126481,126481],\\\"mapped\\\",[1589]],[[126482,126482],\\\"mapped\\\",[1602]],[[126483,126483],\\\"mapped\\\",[1585]],[[126484,126484],\\\"mapped\\\",[1588]],[[126485,126485],\\\"mapped\\\",[1578]],[[126486,126486],\\\"mapped\\\",[1579]],[[126487,126487],\\\"mapped\\\",[1582]],[[126488,126488],\\\"mapped\\\",[1584]],[[126489,126489],\\\"mapped\\\",[1590]],[[126490,126490],\\\"mapped\\\",[1592]],[[126491,126491],\\\"mapped\\\",[1594]],[[126492,126492],\\\"mapped\\\",[1646]],[[126493,126493],\\\"mapped\\\",[1722]],[[126494,126494],\\\"mapped\\\",[1697]],[[126495,126495],\\\"mapped\\\",[1647]],[[126496,126496],\\\"disallowed\\\"],[[126497,126497],\\\"mapped\\\",[1576]],[[126498,126498],\\\"mapped\\\",[1580]],[[126499,126499],\\\"disallowed\\\"],[[126500,126500],\\\"mapped\\\",[1607]],[[126501,126502],\\\"disallowed\\\"],[[126503,126503],\\\"mapped\\\",[1581]],[[126504,126504],\\\"disallowed\\\"],[[126505,126505],\\\"mapped\\\",[1610]],[[126506,126506],\\\"mapped\\\",[1603]],[[126507,126507],\\\"mapped\\\",[1604]],[[126508,126508],\\\"mapped\\\",[1605]],[[126509,126509],\\\"mapped\\\",[1606]],[[126510,126510],\\\"mapped\\\",[1587]],[[126511,126511],\\\"mapped\\\",[1593]],[[126512,126512],\\\"mapped\\\",[1601]],[[126513,126513],\\\"mapped\\\",[1589]],[[126514,126514],\\\"mapped\\\",[1602]],[[126515,126515],\\\"disallowed\\\"],[[126516,126516],\\\"mapped\\\",[1588]],[[126517,126517],\\\"mapped\\\",[1578]],[[126518,126518],\\\"mapped\\\",[1579]],[[126519,126519],\\\"mapped\\\",[1582]],[[126520,126520],\\\"disallowed\\\"],[[126521,126521],\\\"mapped\\\",[1590]],[[126522,126522],\\\"disallowed\\\"],[[126523,126523],\\\"mapped\\\",[1594]],[[126524,126529],\\\"disallowed\\\"],[[126530,126530],\\\"mapped\\\",[1580]],[[126531,126534],\\\"disallowed\\\"],[[126535,126535],\\\"mapped\\\",[1581]],[[126536,126536],\\\"disallowed\\\"],[[126537,126537],\\\"mapped\\\",[1610]],[[126538,126538],\\\"disallowed\\\"],[[126539,126539],\\\"mapped\\\",[1604]],[[126540,126540],\\\"disallowed\\\"],[[126541,126541],\\\"mapped\\\",[1606]],[[126542,126542],\\\"mapped\\\",[1587]],[[126543,126543],\\\"mapped\\\",[1593]],[[126544,126544],\\\"disallowed\\\"],[[126545,126545],\\\"mapped\\\",[1589]],[[126546,126546],\\\"mapped\\\",[1602]],[[126547,126547],\\\"disallowed\\\"],[[126548,126548],\\\"mapped\\\",[1588]],[[126549,126550],\\\"disallowed\\\"],[[126551,126551],\\\"mapped\\\",[1582]],[[126552,126552],\\\"disallowed\\\"],[[126553,126553],\\\"mapped\\\",[1590]],[[126554,126554],\\\"disallowed\\\"],[[126555,126555],\\\"mapped\\\",[1594]],[[126556,126556],\\\"disallowed\\\"],[[126557,126557],\\\"mapped\\\",[1722]],[[126558,126558],\\\"disallowed\\\"],[[126559,126559],\\\"mapped\\\",[1647]],[[126560,126560],\\\"disallowed\\\"],[[126561,126561],\\\"mapped\\\",[1576]],[[126562,126562],\\\"mapped\\\",[1580]],[[126563,126563],\\\"disallowed\\\"],[[126564,126564],\\\"mapped\\\",[1607]],[[126565,126566],\\\"disallowed\\\"],[[126567,126567],\\\"mapped\\\",[1581]],[[126568,126568],\\\"mapped\\\",[1591]],[[126569,126569],\\\"mapped\\\",[1610]],[[126570,126570],\\\"mapped\\\",[1603]],[[126571,126571],\\\"disallowed\\\"],[[126572,126572],\\\"mapped\\\",[1605]],[[126573,126573],\\\"mapped\\\",[1606]],[[126574,126574],\\\"mapped\\\",[1587]],[[126575,126575],\\\"mapped\\\",[1593]],[[126576,126576],\\\"mapped\\\",[1601]],[[126577,126577],\\\"mapped\\\",[1589]],[[126578,126578],\\\"mapped\\\",[1602]],[[126579,126579],\\\"disallowed\\\"],[[126580,126580],\\\"mapped\\\",[1588]],[[126581,126581],\\\"mapped\\\",[1578]],[[126582,126582],\\\"mapped\\\",[1579]],[[126583,126583],\\\"mapped\\\",[1582]],[[126584,126584],\\\"disallowed\\\"],[[126585,126585],\\\"mapped\\\",[1590]],[[126586,126586],\\\"mapped\\\",[1592]],[[126587,126587],\\\"mapped\\\",[1594]],[[126588,126588],\\\"mapped\\\",[1646]],[[126589,126589],\\\"disallowed\\\"],[[126590,126590],\\\"mapped\\\",[1697]],[[126591,126591],\\\"disallowed\\\"],[[126592,126592],\\\"mapped\\\",[1575]],[[126593,126593],\\\"mapped\\\",[1576]],[[126594,126594],\\\"mapped\\\",[1580]],[[126595,126595],\\\"mapped\\\",[1583]],[[126596,126596],\\\"mapped\\\",[1607]],[[126597,126597],\\\"mapped\\\",[1608]],[[126598,126598],\\\"mapped\\\",[1586]],[[126599,126599],\\\"mapped\\\",[1581]],[[126600,126600],\\\"mapped\\\",[1591]],[[126601,126601],\\\"mapped\\\",[1610]],[[126602,126602],\\\"disallowed\\\"],[[126603,126603],\\\"mapped\\\",[1604]],[[126604,126604],\\\"mapped\\\",[1605]],[[126605,126605],\\\"mapped\\\",[1606]],[[126606,126606],\\\"mapped\\\",[1587]],[[126607,126607],\\\"mapped\\\",[1593]],[[126608,126608],\\\"mapped\\\",[1601]],[[126609,126609],\\\"mapped\\\",[1589]],[[126610,126610],\\\"mapped\\\",[1602]],[[126611,126611],\\\"mapped\\\",[1585]],[[126612,126612],\\\"mapped\\\",[1588]],[[126613,126613],\\\"mapped\\\",[1578]],[[126614,126614],\\\"mapped\\\",[1579]],[[126615,126615],\\\"mapped\\\",[1582]],[[126616,126616],\\\"mapped\\\",[1584]],[[126617,126617],\\\"mapped\\\",[1590]],[[126618,126618],\\\"mapped\\\",[1592]],[[126619,126619],\\\"mapped\\\",[1594]],[[126620,126624],\\\"disallowed\\\"],[[126625,126625],\\\"mapped\\\",[1576]],[[126626,126626],\\\"mapped\\\",[1580]],[[126627,126627],\\\"mapped\\\",[1583]],[[126628,126628],\\\"disallowed\\\"],[[126629,126629],\\\"mapped\\\",[1608]],[[126630,126630],\\\"mapped\\\",[1586]],[[126631,126631],\\\"mapped\\\",[1581]],[[126632,126632],\\\"mapped\\\",[1591]],[[126633,126633],\\\"mapped\\\",[1610]],[[126634,126634],\\\"disallowed\\\"],[[126635,126635],\\\"mapped\\\",[1604]],[[126636,126636],\\\"mapped\\\",[1605]],[[126637,126637],\\\"mapped\\\",[1606]],[[126638,126638],\\\"mapped\\\",[1587]],[[126639,126639],\\\"mapped\\\",[1593]],[[126640,126640],\\\"mapped\\\",[1601]],[[126641,126641],\\\"mapped\\\",[1589]],[[126642,126642],\\\"mapped\\\",[1602]],[[126643,126643],\\\"mapped\\\",[1585]],[[126644,126644],\\\"mapped\\\",[1588]],[[126645,126645],\\\"mapped\\\",[1578]],[[126646,126646],\\\"mapped\\\",[1579]],[[126647,126647],\\\"mapped\\\",[1582]],[[126648,126648],\\\"mapped\\\",[1584]],[[126649,126649],\\\"mapped\\\",[1590]],[[126650,126650],\\\"mapped\\\",[1592]],[[126651,126651],\\\"mapped\\\",[1594]],[[126652,126703],\\\"disallowed\\\"],[[126704,126705],\\\"valid\\\",[],\\\"NV8\\\"],[[126706,126975],\\\"disallowed\\\"],[[126976,127019],\\\"valid\\\",[],\\\"NV8\\\"],[[127020,127023],\\\"disallowed\\\"],[[127024,127123],\\\"valid\\\",[],\\\"NV8\\\"],[[127124,127135],\\\"disallowed\\\"],[[127136,127150],\\\"valid\\\",[],\\\"NV8\\\"],[[127151,127152],\\\"disallowed\\\"],[[127153,127166],\\\"valid\\\",[],\\\"NV8\\\"],[[127167,127167],\\\"valid\\\",[],\\\"NV8\\\"],[[127168,127168],\\\"disallowed\\\"],[[127169,127183],\\\"valid\\\",[],\\\"NV8\\\"],[[127184,127184],\\\"disallowed\\\"],[[127185,127199],\\\"valid\\\",[],\\\"NV8\\\"],[[127200,127221],\\\"valid\\\",[],\\\"NV8\\\"],[[127222,127231],\\\"disallowed\\\"],[[127232,127232],\\\"disallowed\\\"],[[127233,127233],\\\"disallowed_STD3_mapped\\\",[48,44]],[[127234,127234],\\\"disallowed_STD3_mapped\\\",[49,44]],[[127235,127235],\\\"disallowed_STD3_mapped\\\",[50,44]],[[127236,127236],\\\"disallowed_STD3_mapped\\\",[51,44]],[[127237,127237],\\\"disallowed_STD3_mapped\\\",[52,44]],[[127238,127238],\\\"disallowed_STD3_mapped\\\",[53,44]],[[127239,127239],\\\"disallowed_STD3_mapped\\\",[54,44]],[[127240,127240],\\\"disallowed_STD3_mapped\\\",[55,44]],[[127241,127241],\\\"disallowed_STD3_mapped\\\",[56,44]],[[127242,127242],\\\"disallowed_STD3_mapped\\\",[57,44]],[[127243,127244],\\\"valid\\\",[],\\\"NV8\\\"],[[127245,127247],\\\"disallowed\\\"],[[127248,127248],\\\"disallowed_STD3_mapped\\\",[40,97,41]],[[127249,127249],\\\"disallowed_STD3_mapped\\\",[40,98,41]],[[127250,127250],\\\"disallowed_STD3_mapped\\\",[40,99,41]],[[127251,127251],\\\"disallowed_STD3_mapped\\\",[40,100,41]],[[127252,127252],\\\"disallowed_STD3_mapped\\\",[40,101,41]],[[127253,127253],\\\"disallowed_STD3_mapped\\\",[40,102,41]],[[127254,127254],\\\"disallowed_STD3_mapped\\\",[40,103,41]],[[127255,127255],\\\"disallowed_STD3_mapped\\\",[40,104,41]],[[127256,127256],\\\"disallowed_STD3_mapped\\\",[40,105,41]],[[127257,127257],\\\"disallowed_STD3_mapped\\\",[40,106,41]],[[127258,127258],\\\"disallowed_STD3_mapped\\\",[40,107,41]],[[127259,127259],\\\"disallowed_STD3_mapped\\\",[40,108,41]],[[127260,127260],\\\"disallowed_STD3_mapped\\\",[40,109,41]],[[127261,127261],\\\"disallowed_STD3_mapped\\\",[40,110,41]],[[127262,127262],\\\"disallowed_STD3_mapped\\\",[40,111,41]],[[127263,127263],\\\"disallowed_STD3_mapped\\\",[40,112,41]],[[127264,127264],\\\"disallowed_STD3_mapped\\\",[40,113,41]],[[127265,127265],\\\"disallowed_STD3_mapped\\\",[40,114,41]],[[127266,127266],\\\"disallowed_STD3_mapped\\\",[40,115,41]],[[127267,127267],\\\"disallowed_STD3_mapped\\\",[40,116,41]],[[127268,127268],\\\"disallowed_STD3_mapped\\\",[40,117,41]],[[127269,127269],\\\"disallowed_STD3_mapped\\\",[40,118,41]],[[127270,127270],\\\"disallowed_STD3_mapped\\\",[40,119,41]],[[127271,127271],\\\"disallowed_STD3_mapped\\\",[40,120,41]],[[127272,127272],\\\"disallowed_STD3_mapped\\\",[40,121,41]],[[127273,127273],\\\"disallowed_STD3_mapped\\\",[40,122,41]],[[127274,127274],\\\"mapped\\\",[12308,115,12309]],[[127275,127275],\\\"mapped\\\",[99]],[[127276,127276],\\\"mapped\\\",[114]],[[127277,127277],\\\"mapped\\\",[99,100]],[[127278,127278],\\\"mapped\\\",[119,122]],[[127279,127279],\\\"disallowed\\\"],[[127280,127280],\\\"mapped\\\",[97]],[[127281,127281],\\\"mapped\\\",[98]],[[127282,127282],\\\"mapped\\\",[99]],[[127283,127283],\\\"mapped\\\",[100]],[[127284,127284],\\\"mapped\\\",[101]],[[127285,127285],\\\"mapped\\\",[102]],[[127286,127286],\\\"mapped\\\",[103]],[[127287,127287],\\\"mapped\\\",[104]],[[127288,127288],\\\"mapped\\\",[105]],[[127289,127289],\\\"mapped\\\",[106]],[[127290,127290],\\\"mapped\\\",[107]],[[127291,127291],\\\"mapped\\\",[108]],[[127292,127292],\\\"mapped\\\",[109]],[[127293,127293],\\\"mapped\\\",[110]],[[127294,127294],\\\"mapped\\\",[111]],[[127295,127295],\\\"mapped\\\",[112]],[[127296,127296],\\\"mapped\\\",[113]],[[127297,127297],\\\"mapped\\\",[114]],[[127298,127298],\\\"mapped\\\",[115]],[[127299,127299],\\\"mapped\\\",[116]],[[127300,127300],\\\"mapped\\\",[117]],[[127301,127301],\\\"mapped\\\",[118]],[[127302,127302],\\\"mapped\\\",[119]],[[127303,127303],\\\"mapped\\\",[120]],[[127304,127304],\\\"mapped\\\",[121]],[[127305,127305],\\\"mapped\\\",[122]],[[127306,127306],\\\"mapped\\\",[104,118]],[[127307,127307],\\\"mapped\\\",[109,118]],[[127308,127308],\\\"mapped\\\",[115,100]],[[127309,127309],\\\"mapped\\\",[115,115]],[[127310,127310],\\\"mapped\\\",[112,112,118]],[[127311,127311],\\\"mapped\\\",[119,99]],[[127312,127318],\\\"valid\\\",[],\\\"NV8\\\"],[[127319,127319],\\\"valid\\\",[],\\\"NV8\\\"],[[127320,127326],\\\"valid\\\",[],\\\"NV8\\\"],[[127327,127327],\\\"valid\\\",[],\\\"NV8\\\"],[[127328,127337],\\\"valid\\\",[],\\\"NV8\\\"],[[127338,127338],\\\"mapped\\\",[109,99]],[[127339,127339],\\\"mapped\\\",[109,100]],[[127340,127343],\\\"disallowed\\\"],[[127344,127352],\\\"valid\\\",[],\\\"NV8\\\"],[[127353,127353],\\\"valid\\\",[],\\\"NV8\\\"],[[127354,127354],\\\"valid\\\",[],\\\"NV8\\\"],[[127355,127356],\\\"valid\\\",[],\\\"NV8\\\"],[[127357,127358],\\\"valid\\\",[],\\\"NV8\\\"],[[127359,127359],\\\"valid\\\",[],\\\"NV8\\\"],[[127360,127369],\\\"valid\\\",[],\\\"NV8\\\"],[[127370,127373],\\\"valid\\\",[],\\\"NV8\\\"],[[127374,127375],\\\"valid\\\",[],\\\"NV8\\\"],[[127376,127376],\\\"mapped\\\",[100,106]],[[127377,127386],\\\"valid\\\",[],\\\"NV8\\\"],[[127387,127461],\\\"disallowed\\\"],[[127462,127487],\\\"valid\\\",[],\\\"NV8\\\"],[[127488,127488],\\\"mapped\\\",[12411,12363]],[[127489,127489],\\\"mapped\\\",[12467,12467]],[[127490,127490],\\\"mapped\\\",[12469]],[[127491,127503],\\\"disallowed\\\"],[[127504,127504],\\\"mapped\\\",[25163]],[[127505,127505],\\\"mapped\\\",[23383]],[[127506,127506],\\\"mapped\\\",[21452]],[[127507,127507],\\\"mapped\\\",[12487]],[[127508,127508],\\\"mapped\\\",[20108]],[[127509,127509],\\\"mapped\\\",[22810]],[[127510,127510],\\\"mapped\\\",[35299]],[[127511,127511],\\\"mapped\\\",[22825]],[[127512,127512],\\\"mapped\\\",[20132]],[[127513,127513],\\\"mapped\\\",[26144]],[[127514,127514],\\\"mapped\\\",[28961]],[[127515,127515],\\\"mapped\\\",[26009]],[[127516,127516],\\\"mapped\\\",[21069]],[[127517,127517],\\\"mapped\\\",[24460]],[[127518,127518],\\\"mapped\\\",[20877]],[[127519,127519],\\\"mapped\\\",[26032]],[[127520,127520],\\\"mapped\\\",[21021]],[[127521,127521],\\\"mapped\\\",[32066]],[[127522,127522],\\\"mapped\\\",[29983]],[[127523,127523],\\\"mapped\\\",[36009]],[[127524,127524],\\\"mapped\\\",[22768]],[[127525,127525],\\\"mapped\\\",[21561]],[[127526,127526],\\\"mapped\\\",[28436]],[[127527,127527],\\\"mapped\\\",[25237]],[[127528,127528],\\\"mapped\\\",[25429]],[[127529,127529],\\\"mapped\\\",[19968]],[[127530,127530],\\\"mapped\\\",[19977]],[[127531,127531],\\\"mapped\\\",[36938]],[[127532,127532],\\\"mapped\\\",[24038]],[[127533,127533],\\\"mapped\\\",[20013]],[[127534,127534],\\\"mapped\\\",[21491]],[[127535,127535],\\\"mapped\\\",[25351]],[[127536,127536],\\\"mapped\\\",[36208]],[[127537,127537],\\\"mapped\\\",[25171]],[[127538,127538],\\\"mapped\\\",[31105]],[[127539,127539],\\\"mapped\\\",[31354]],[[127540,127540],\\\"mapped\\\",[21512]],[[127541,127541],\\\"mapped\\\",[28288]],[[127542,127542],\\\"mapped\\\",[26377]],[[127543,127543],\\\"mapped\\\",[26376]],[[127544,127544],\\\"mapped\\\",[30003]],[[127545,127545],\\\"mapped\\\",[21106]],[[127546,127546],\\\"mapped\\\",[21942]],[[127547,127551],\\\"disallowed\\\"],[[127552,127552],\\\"mapped\\\",[12308,26412,12309]],[[127553,127553],\\\"mapped\\\",[12308,19977,12309]],[[127554,127554],\\\"mapped\\\",[12308,20108,12309]],[[127555,127555],\\\"mapped\\\",[12308,23433,12309]],[[127556,127556],\\\"mapped\\\",[12308,28857,12309]],[[127557,127557],\\\"mapped\\\",[12308,25171,12309]],[[127558,127558],\\\"mapped\\\",[12308,30423,12309]],[[127559,127559],\\\"mapped\\\",[12308,21213,12309]],[[127560,127560],\\\"mapped\\\",[12308,25943,12309]],[[127561,127567],\\\"disallowed\\\"],[[127568,127568],\\\"mapped\\\",[24471]],[[127569,127569],\\\"mapped\\\",[21487]],[[127570,127743],\\\"disallowed\\\"],[[127744,127776],\\\"valid\\\",[],\\\"NV8\\\"],[[127777,127788],\\\"valid\\\",[],\\\"NV8\\\"],[[127789,127791],\\\"valid\\\",[],\\\"NV8\\\"],[[127792,127797],\\\"valid\\\",[],\\\"NV8\\\"],[[127798,127798],\\\"valid\\\",[],\\\"NV8\\\"],[[127799,127868],\\\"valid\\\",[],\\\"NV8\\\"],[[127869,127869],\\\"valid\\\",[],\\\"NV8\\\"],[[127870,127871],\\\"valid\\\",[],\\\"NV8\\\"],[[127872,127891],\\\"valid\\\",[],\\\"NV8\\\"],[[127892,127903],\\\"valid\\\",[],\\\"NV8\\\"],[[127904,127940],\\\"valid\\\",[],\\\"NV8\\\"],[[127941,127941],\\\"valid\\\",[],\\\"NV8\\\"],[[127942,127946],\\\"valid\\\",[],\\\"NV8\\\"],[[127947,127950],\\\"valid\\\",[],\\\"NV8\\\"],[[127951,127955],\\\"valid\\\",[],\\\"NV8\\\"],[[127956,127967],\\\"valid\\\",[],\\\"NV8\\\"],[[127968,127984],\\\"valid\\\",[],\\\"NV8\\\"],[[127985,127991],\\\"valid\\\",[],\\\"NV8\\\"],[[127992,127999],\\\"valid\\\",[],\\\"NV8\\\"],[[128000,128062],\\\"valid\\\",[],\\\"NV8\\\"],[[128063,128063],\\\"valid\\\",[],\\\"NV8\\\"],[[128064,128064],\\\"valid\\\",[],\\\"NV8\\\"],[[128065,128065],\\\"valid\\\",[],\\\"NV8\\\"],[[128066,128247],\\\"valid\\\",[],\\\"NV8\\\"],[[128248,128248],\\\"valid\\\",[],\\\"NV8\\\"],[[128249,128252],\\\"valid\\\",[],\\\"NV8\\\"],[[128253,128254],\\\"valid\\\",[],\\\"NV8\\\"],[[128255,128255],\\\"valid\\\",[],\\\"NV8\\\"],[[128256,128317],\\\"valid\\\",[],\\\"NV8\\\"],[[128318,128319],\\\"valid\\\",[],\\\"NV8\\\"],[[128320,128323],\\\"valid\\\",[],\\\"NV8\\\"],[[128324,128330],\\\"valid\\\",[],\\\"NV8\\\"],[[128331,128335],\\\"valid\\\",[],\\\"NV8\\\"],[[128336,128359],\\\"valid\\\",[],\\\"NV8\\\"],[[128360,128377],\\\"valid\\\",[],\\\"NV8\\\"],[[128378,128378],\\\"disallowed\\\"],[[128379,128419],\\\"valid\\\",[],\\\"NV8\\\"],[[128420,128420],\\\"disallowed\\\"],[[128421,128506],\\\"valid\\\",[],\\\"NV8\\\"],[[128507,128511],\\\"valid\\\",[],\\\"NV8\\\"],[[128512,128512],\\\"valid\\\",[],\\\"NV8\\\"],[[128513,128528],\\\"valid\\\",[],\\\"NV8\\\"],[[128529,128529],\\\"valid\\\",[],\\\"NV8\\\"],[[128530,128532],\\\"valid\\\",[],\\\"NV8\\\"],[[128533,128533],\\\"valid\\\",[],\\\"NV8\\\"],[[128534,128534],\\\"valid\\\",[],\\\"NV8\\\"],[[128535,128535],\\\"valid\\\",[],\\\"NV8\\\"],[[128536,128536],\\\"valid\\\",[],\\\"NV8\\\"],[[128537,128537],\\\"valid\\\",[],\\\"NV8\\\"],[[128538,128538],\\\"valid\\\",[],\\\"NV8\\\"],[[128539,128539],\\\"valid\\\",[],\\\"NV8\\\"],[[128540,128542],\\\"valid\\\",[],\\\"NV8\\\"],[[128543,128543],\\\"valid\\\",[],\\\"NV8\\\"],[[128544,128549],\\\"valid\\\",[],\\\"NV8\\\"],[[128550,128551],\\\"valid\\\",[],\\\"NV8\\\"],[[128552,128555],\\\"valid\\\",[],\\\"NV8\\\"],[[128556,128556],\\\"valid\\\",[],\\\"NV8\\\"],[[128557,128557],\\\"valid\\\",[],\\\"NV8\\\"],[[128558,128559],\\\"valid\\\",[],\\\"NV8\\\"],[[128560,128563],\\\"valid\\\",[],\\\"NV8\\\"],[[128564,128564],\\\"valid\\\",[],\\\"NV8\\\"],[[128565,128576],\\\"valid\\\",[],\\\"NV8\\\"],[[128577,128578],\\\"valid\\\",[],\\\"NV8\\\"],[[128579,128580],\\\"valid\\\",[],\\\"NV8\\\"],[[128581,128591],\\\"valid\\\",[],\\\"NV8\\\"],[[128592,128639],\\\"valid\\\",[],\\\"NV8\\\"],[[128640,128709],\\\"valid\\\",[],\\\"NV8\\\"],[[128710,128719],\\\"valid\\\",[],\\\"NV8\\\"],[[128720,128720],\\\"valid\\\",[],\\\"NV8\\\"],[[128721,128735],\\\"disallowed\\\"],[[128736,128748],\\\"valid\\\",[],\\\"NV8\\\"],[[128749,128751],\\\"disallowed\\\"],[[128752,128755],\\\"valid\\\",[],\\\"NV8\\\"],[[128756,128767],\\\"disallowed\\\"],[[128768,128883],\\\"valid\\\",[],\\\"NV8\\\"],[[128884,128895],\\\"disallowed\\\"],[[128896,128980],\\\"valid\\\",[],\\\"NV8\\\"],[[128981,129023],\\\"disallowed\\\"],[[129024,129035],\\\"valid\\\",[],\\\"NV8\\\"],[[129036,129039],\\\"disallowed\\\"],[[129040,129095],\\\"valid\\\",[],\\\"NV8\\\"],[[129096,129103],\\\"disallowed\\\"],[[129104,129113],\\\"valid\\\",[],\\\"NV8\\\"],[[129114,129119],\\\"disallowed\\\"],[[129120,129159],\\\"valid\\\",[],\\\"NV8\\\"],[[129160,129167],\\\"disallowed\\\"],[[129168,129197],\\\"valid\\\",[],\\\"NV8\\\"],[[129198,129295],\\\"disallowed\\\"],[[129296,129304],\\\"valid\\\",[],\\\"NV8\\\"],[[129305,129407],\\\"disallowed\\\"],[[129408,129412],\\\"valid\\\",[],\\\"NV8\\\"],[[129413,129471],\\\"disallowed\\\"],[[129472,129472],\\\"valid\\\",[],\\\"NV8\\\"],[[129473,131069],\\\"disallowed\\\"],[[131070,131071],\\\"disallowed\\\"],[[131072,173782],\\\"valid\\\"],[[173783,173823],\\\"disallowed\\\"],[[173824,177972],\\\"valid\\\"],[[177973,177983],\\\"disallowed\\\"],[[177984,178205],\\\"valid\\\"],[[178206,178207],\\\"disallowed\\\"],[[178208,183969],\\\"valid\\\"],[[183970,194559],\\\"disallowed\\\"],[[194560,194560],\\\"mapped\\\",[20029]],[[194561,194561],\\\"mapped\\\",[20024]],[[194562,194562],\\\"mapped\\\",[20033]],[[194563,194563],\\\"mapped\\\",[131362]],[[194564,194564],\\\"mapped\\\",[20320]],[[194565,194565],\\\"mapped\\\",[20398]],[[194566,194566],\\\"mapped\\\",[20411]],[[194567,194567],\\\"mapped\\\",[20482]],[[194568,194568],\\\"mapped\\\",[20602]],[[194569,194569],\\\"mapped\\\",[20633]],[[194570,194570],\\\"mapped\\\",[20711]],[[194571,194571],\\\"mapped\\\",[20687]],[[194572,194572],\\\"mapped\\\",[13470]],[[194573,194573],\\\"mapped\\\",[132666]],[[194574,194574],\\\"mapped\\\",[20813]],[[194575,194575],\\\"mapped\\\",[20820]],[[194576,194576],\\\"mapped\\\",[20836]],[[194577,194577],\\\"mapped\\\",[20855]],[[194578,194578],\\\"mapped\\\",[132380]],[[194579,194579],\\\"mapped\\\",[13497]],[[194580,194580],\\\"mapped\\\",[20839]],[[194581,194581],\\\"mapped\\\",[20877]],[[194582,194582],\\\"mapped\\\",[132427]],[[194583,194583],\\\"mapped\\\",[20887]],[[194584,194584],\\\"mapped\\\",[20900]],[[194585,194585],\\\"mapped\\\",[20172]],[[194586,194586],\\\"mapped\\\",[20908]],[[194587,194587],\\\"mapped\\\",[20917]],[[194588,194588],\\\"mapped\\\",[168415]],[[194589,194589],\\\"mapped\\\",[20981]],[[194590,194590],\\\"mapped\\\",[20995]],[[194591,194591],\\\"mapped\\\",[13535]],[[194592,194592],\\\"mapped\\\",[21051]],[[194593,194593],\\\"mapped\\\",[21062]],[[194594,194594],\\\"mapped\\\",[21106]],[[194595,194595],\\\"mapped\\\",[21111]],[[194596,194596],\\\"mapped\\\",[13589]],[[194597,194597],\\\"mapped\\\",[21191]],[[194598,194598],\\\"mapped\\\",[21193]],[[194599,194599],\\\"mapped\\\",[21220]],[[194600,194600],\\\"mapped\\\",[21242]],[[194601,194601],\\\"mapped\\\",[21253]],[[194602,194602],\\\"mapped\\\",[21254]],[[194603,194603],\\\"mapped\\\",[21271]],[[194604,194604],\\\"mapped\\\",[21321]],[[194605,194605],\\\"mapped\\\",[21329]],[[194606,194606],\\\"mapped\\\",[21338]],[[194607,194607],\\\"mapped\\\",[21363]],[[194608,194608],\\\"mapped\\\",[21373]],[[194609,194611],\\\"mapped\\\",[21375]],[[194612,194612],\\\"mapped\\\",[133676]],[[194613,194613],\\\"mapped\\\",[28784]],[[194614,194614],\\\"mapped\\\",[21450]],[[194615,194615],\\\"mapped\\\",[21471]],[[194616,194616],\\\"mapped\\\",[133987]],[[194617,194617],\\\"mapped\\\",[21483]],[[194618,194618],\\\"mapped\\\",[21489]],[[194619,194619],\\\"mapped\\\",[21510]],[[194620,194620],\\\"mapped\\\",[21662]],[[194621,194621],\\\"mapped\\\",[21560]],[[194622,194622],\\\"mapped\\\",[21576]],[[194623,194623],\\\"mapped\\\",[21608]],[[194624,194624],\\\"mapped\\\",[21666]],[[194625,194625],\\\"mapped\\\",[21750]],[[194626,194626],\\\"mapped\\\",[21776]],[[194627,194627],\\\"mapped\\\",[21843]],[[194628,194628],\\\"mapped\\\",[21859]],[[194629,194630],\\\"mapped\\\",[21892]],[[194631,194631],\\\"mapped\\\",[21913]],[[194632,194632],\\\"mapped\\\",[21931]],[[194633,194633],\\\"mapped\\\",[21939]],[[194634,194634],\\\"mapped\\\",[21954]],[[194635,194635],\\\"mapped\\\",[22294]],[[194636,194636],\\\"mapped\\\",[22022]],[[194637,194637],\\\"mapped\\\",[22295]],[[194638,194638],\\\"mapped\\\",[22097]],[[194639,194639],\\\"mapped\\\",[22132]],[[194640,194640],\\\"mapped\\\",[20999]],[[194641,194641],\\\"mapped\\\",[22766]],[[194642,194642],\\\"mapped\\\",[22478]],[[194643,194643],\\\"mapped\\\",[22516]],[[194644,194644],\\\"mapped\\\",[22541]],[[194645,194645],\\\"mapped\\\",[22411]],[[194646,194646],\\\"mapped\\\",[22578]],[[194647,194647],\\\"mapped\\\",[22577]],[[194648,194648],\\\"mapped\\\",[22700]],[[194649,194649],\\\"mapped\\\",[136420]],[[194650,194650],\\\"mapped\\\",[22770]],[[194651,194651],\\\"mapped\\\",[22775]],[[194652,194652],\\\"mapped\\\",[22790]],[[194653,194653],\\\"mapped\\\",[22810]],[[194654,194654],\\\"mapped\\\",[22818]],[[194655,194655],\\\"mapped\\\",[22882]],[[194656,194656],\\\"mapped\\\",[136872]],[[194657,194657],\\\"mapped\\\",[136938]],[[194658,194658],\\\"mapped\\\",[23020]],[[194659,194659],\\\"mapped\\\",[23067]],[[194660,194660],\\\"mapped\\\",[23079]],[[194661,194661],\\\"mapped\\\",[23000]],[[194662,194662],\\\"mapped\\\",[23142]],[[194663,194663],\\\"mapped\\\",[14062]],[[194664,194664],\\\"disallowed\\\"],[[194665,194665],\\\"mapped\\\",[23304]],[[194666,194667],\\\"mapped\\\",[23358]],[[194668,194668],\\\"mapped\\\",[137672]],[[194669,194669],\\\"mapped\\\",[23491]],[[194670,194670],\\\"mapped\\\",[23512]],[[194671,194671],\\\"mapped\\\",[23527]],[[194672,194672],\\\"mapped\\\",[23539]],[[194673,194673],\\\"mapped\\\",[138008]],[[194674,194674],\\\"mapped\\\",[23551]],[[194675,194675],\\\"mapped\\\",[23558]],[[194676,194676],\\\"disallowed\\\"],[[194677,194677],\\\"mapped\\\",[23586]],[[194678,194678],\\\"mapped\\\",[14209]],[[194679,194679],\\\"mapped\\\",[23648]],[[194680,194680],\\\"mapped\\\",[23662]],[[194681,194681],\\\"mapped\\\",[23744]],[[194682,194682],\\\"mapped\\\",[23693]],[[194683,194683],\\\"mapped\\\",[138724]],[[194684,194684],\\\"mapped\\\",[23875]],[[194685,194685],\\\"mapped\\\",[138726]],[[194686,194686],\\\"mapped\\\",[23918]],[[194687,194687],\\\"mapped\\\",[23915]],[[194688,194688],\\\"mapped\\\",[23932]],[[194689,194689],\\\"mapped\\\",[24033]],[[194690,194690],\\\"mapped\\\",[24034]],[[194691,194691],\\\"mapped\\\",[14383]],[[194692,194692],\\\"mapped\\\",[24061]],[[194693,194693],\\\"mapped\\\",[24104]],[[194694,194694],\\\"mapped\\\",[24125]],[[194695,194695],\\\"mapped\\\",[24169]],[[194696,194696],\\\"mapped\\\",[14434]],[[194697,194697],\\\"mapped\\\",[139651]],[[194698,194698],\\\"mapped\\\",[14460]],[[194699,194699],\\\"mapped\\\",[24240]],[[194700,194700],\\\"mapped\\\",[24243]],[[194701,194701],\\\"mapped\\\",[24246]],[[194702,194702],\\\"mapped\\\",[24266]],[[194703,194703],\\\"mapped\\\",[172946]],[[194704,194704],\\\"mapped\\\",[24318]],[[194705,194706],\\\"mapped\\\",[140081]],[[194707,194707],\\\"mapped\\\",[33281]],[[194708,194709],\\\"mapped\\\",[24354]],[[194710,194710],\\\"mapped\\\",[14535]],[[194711,194711],\\\"mapped\\\",[144056]],[[194712,194712],\\\"mapped\\\",[156122]],[[194713,194713],\\\"mapped\\\",[24418]],[[194714,194714],\\\"mapped\\\",[24427]],[[194715,194715],\\\"mapped\\\",[14563]],[[194716,194716],\\\"mapped\\\",[24474]],[[194717,194717],\\\"mapped\\\",[24525]],[[194718,194718],\\\"mapped\\\",[24535]],[[194719,194719],\\\"mapped\\\",[24569]],[[194720,194720],\\\"mapped\\\",[24705]],[[194721,194721],\\\"mapped\\\",[14650]],[[194722,194722],\\\"mapped\\\",[14620]],[[194723,194723],\\\"mapped\\\",[24724]],[[194724,194724],\\\"mapped\\\",[141012]],[[194725,194725],\\\"mapped\\\",[24775]],[[194726,194726],\\\"mapped\\\",[24904]],[[194727,194727],\\\"mapped\\\",[24908]],[[194728,194728],\\\"mapped\\\",[24910]],[[194729,194729],\\\"mapped\\\",[24908]],[[194730,194730],\\\"mapped\\\",[24954]],[[194731,194731],\\\"mapped\\\",[24974]],[[194732,194732],\\\"mapped\\\",[25010]],[[194733,194733],\\\"mapped\\\",[24996]],[[194734,194734],\\\"mapped\\\",[25007]],[[194735,194735],\\\"mapped\\\",[25054]],[[194736,194736],\\\"mapped\\\",[25074]],[[194737,194737],\\\"mapped\\\",[25078]],[[194738,194738],\\\"mapped\\\",[25104]],[[194739,194739],\\\"mapped\\\",[25115]],[[194740,194740],\\\"mapped\\\",[25181]],[[194741,194741],\\\"mapped\\\",[25265]],[[194742,194742],\\\"mapped\\\",[25300]],[[194743,194743],\\\"mapped\\\",[25424]],[[194744,194744],\\\"mapped\\\",[142092]],[[194745,194745],\\\"mapped\\\",[25405]],[[194746,194746],\\\"mapped\\\",[25340]],[[194747,194747],\\\"mapped\\\",[25448]],[[194748,194748],\\\"mapped\\\",[25475]],[[194749,194749],\\\"mapped\\\",[25572]],[[194750,194750],\\\"mapped\\\",[142321]],[[194751,194751],\\\"mapped\\\",[25634]],[[194752,194752],\\\"mapped\\\",[25541]],[[194753,194753],\\\"mapped\\\",[25513]],[[194754,194754],\\\"mapped\\\",[14894]],[[194755,194755],\\\"mapped\\\",[25705]],[[194756,194756],\\\"mapped\\\",[25726]],[[194757,194757],\\\"mapped\\\",[25757]],[[194758,194758],\\\"mapped\\\",[25719]],[[194759,194759],\\\"mapped\\\",[14956]],[[194760,194760],\\\"mapped\\\",[25935]],[[194761,194761],\\\"mapped\\\",[25964]],[[194762,194762],\\\"mapped\\\",[143370]],[[194763,194763],\\\"mapped\\\",[26083]],[[194764,194764],\\\"mapped\\\",[26360]],[[194765,194765],\\\"mapped\\\",[26185]],[[194766,194766],\\\"mapped\\\",[15129]],[[194767,194767],\\\"mapped\\\",[26257]],[[194768,194768],\\\"mapped\\\",[15112]],[[194769,194769],\\\"mapped\\\",[15076]],[[194770,194770],\\\"mapped\\\",[20882]],[[194771,194771],\\\"mapped\\\",[20885]],[[194772,194772],\\\"mapped\\\",[26368]],[[194773,194773],\\\"mapped\\\",[26268]],[[194774,194774],\\\"mapped\\\",[32941]],[[194775,194775],\\\"mapped\\\",[17369]],[[194776,194776],\\\"mapped\\\",[26391]],[[194777,194777],\\\"mapped\\\",[26395]],[[194778,194778],\\\"mapped\\\",[26401]],[[194779,194779],\\\"mapped\\\",[26462]],[[194780,194780],\\\"mapped\\\",[26451]],[[194781,194781],\\\"mapped\\\",[144323]],[[194782,194782],\\\"mapped\\\",[15177]],[[194783,194783],\\\"mapped\\\",[26618]],[[194784,194784],\\\"mapped\\\",[26501]],[[194785,194785],\\\"mapped\\\",[26706]],[[194786,194786],\\\"mapped\\\",[26757]],[[194787,194787],\\\"mapped\\\",[144493]],[[194788,194788],\\\"mapped\\\",[26766]],[[194789,194789],\\\"mapped\\\",[26655]],[[194790,194790],\\\"mapped\\\",[26900]],[[194791,194791],\\\"mapped\\\",[15261]],[[194792,194792],\\\"mapped\\\",[26946]],[[194793,194793],\\\"mapped\\\",[27043]],[[194794,194794],\\\"mapped\\\",[27114]],[[194795,194795],\\\"mapped\\\",[27304]],[[194796,194796],\\\"mapped\\\",[145059]],[[194797,194797],\\\"mapped\\\",[27355]],[[194798,194798],\\\"mapped\\\",[15384]],[[194799,194799],\\\"mapped\\\",[27425]],[[194800,194800],\\\"mapped\\\",[145575]],[[194801,194801],\\\"mapped\\\",[27476]],[[194802,194802],\\\"mapped\\\",[15438]],[[194803,194803],\\\"mapped\\\",[27506]],[[194804,194804],\\\"mapped\\\",[27551]],[[194805,194805],\\\"mapped\\\",[27578]],[[194806,194806],\\\"mapped\\\",[27579]],[[194807,194807],\\\"mapped\\\",[146061]],[[194808,194808],\\\"mapped\\\",[138507]],[[194809,194809],\\\"mapped\\\",[146170]],[[194810,194810],\\\"mapped\\\",[27726]],[[194811,194811],\\\"mapped\\\",[146620]],[[194812,194812],\\\"mapped\\\",[27839]],[[194813,194813],\\\"mapped\\\",[27853]],[[194814,194814],\\\"mapped\\\",[27751]],[[194815,194815],\\\"mapped\\\",[27926]],[[194816,194816],\\\"mapped\\\",[27966]],[[194817,194817],\\\"mapped\\\",[28023]],[[194818,194818],\\\"mapped\\\",[27969]],[[194819,194819],\\\"mapped\\\",[28009]],[[194820,194820],\\\"mapped\\\",[28024]],[[194821,194821],\\\"mapped\\\",[28037]],[[194822,194822],\\\"mapped\\\",[146718]],[[194823,194823],\\\"mapped\\\",[27956]],[[194824,194824],\\\"mapped\\\",[28207]],[[194825,194825],\\\"mapped\\\",[28270]],[[194826,194826],\\\"mapped\\\",[15667]],[[194827,194827],\\\"mapped\\\",[28363]],[[194828,194828],\\\"mapped\\\",[28359]],[[194829,194829],\\\"mapped\\\",[147153]],[[194830,194830],\\\"mapped\\\",[28153]],[[194831,194831],\\\"mapped\\\",[28526]],[[194832,194832],\\\"mapped\\\",[147294]],[[194833,194833],\\\"mapped\\\",[147342]],[[194834,194834],\\\"mapped\\\",[28614]],[[194835,194835],\\\"mapped\\\",[28729]],[[194836,194836],\\\"mapped\\\",[28702]],[[194837,194837],\\\"mapped\\\",[28699]],[[194838,194838],\\\"mapped\\\",[15766]],[[194839,194839],\\\"mapped\\\",[28746]],[[194840,194840],\\\"mapped\\\",[28797]],[[194841,194841],\\\"mapped\\\",[28791]],[[194842,194842],\\\"mapped\\\",[28845]],[[194843,194843],\\\"mapped\\\",[132389]],[[194844,194844],\\\"mapped\\\",[28997]],[[194845,194845],\\\"mapped\\\",[148067]],[[194846,194846],\\\"mapped\\\",[29084]],[[194847,194847],\\\"disallowed\\\"],[[194848,194848],\\\"mapped\\\",[29224]],[[194849,194849],\\\"mapped\\\",[29237]],[[194850,194850],\\\"mapped\\\",[29264]],[[194851,194851],\\\"mapped\\\",[149000]],[[194852,194852],\\\"mapped\\\",[29312]],[[194853,194853],\\\"mapped\\\",[29333]],[[194854,194854],\\\"mapped\\\",[149301]],[[194855,194855],\\\"mapped\\\",[149524]],[[194856,194856],\\\"mapped\\\",[29562]],[[194857,194857],\\\"mapped\\\",[29579]],[[194858,194858],\\\"mapped\\\",[16044]],[[194859,194859],\\\"mapped\\\",[29605]],[[194860,194861],\\\"mapped\\\",[16056]],[[194862,194862],\\\"mapped\\\",[29767]],[[194863,194863],\\\"mapped\\\",[29788]],[[194864,194864],\\\"mapped\\\",[29809]],[[194865,194865],\\\"mapped\\\",[29829]],[[194866,194866],\\\"mapped\\\",[29898]],[[194867,194867],\\\"mapped\\\",[16155]],[[194868,194868],\\\"mapped\\\",[29988]],[[194869,194869],\\\"mapped\\\",[150582]],[[194870,194870],\\\"mapped\\\",[30014]],[[194871,194871],\\\"mapped\\\",[150674]],[[194872,194872],\\\"mapped\\\",[30064]],[[194873,194873],\\\"mapped\\\",[139679]],[[194874,194874],\\\"mapped\\\",[30224]],[[194875,194875],\\\"mapped\\\",[151457]],[[194876,194876],\\\"mapped\\\",[151480]],[[194877,194877],\\\"mapped\\\",[151620]],[[194878,194878],\\\"mapped\\\",[16380]],[[194879,194879],\\\"mapped\\\",[16392]],[[194880,194880],\\\"mapped\\\",[30452]],[[194881,194881],\\\"mapped\\\",[151795]],[[194882,194882],\\\"mapped\\\",[151794]],[[194883,194883],\\\"mapped\\\",[151833]],[[194884,194884],\\\"mapped\\\",[151859]],[[194885,194885],\\\"mapped\\\",[30494]],[[194886,194887],\\\"mapped\\\",[30495]],[[194888,194888],\\\"mapped\\\",[30538]],[[194889,194889],\\\"mapped\\\",[16441]],[[194890,194890],\\\"mapped\\\",[30603]],[[194891,194891],\\\"mapped\\\",[16454]],[[194892,194892],\\\"mapped\\\",[16534]],[[194893,194893],\\\"mapped\\\",[152605]],[[194894,194894],\\\"mapped\\\",[30798]],[[194895,194895],\\\"mapped\\\",[30860]],[[194896,194896],\\\"mapped\\\",[30924]],[[194897,194897],\\\"mapped\\\",[16611]],[[194898,194898],\\\"mapped\\\",[153126]],[[194899,194899],\\\"mapped\\\",[31062]],[[194900,194900],\\\"mapped\\\",[153242]],[[194901,194901],\\\"mapped\\\",[153285]],[[194902,194902],\\\"mapped\\\",[31119]],[[194903,194903],\\\"mapped\\\",[31211]],[[194904,194904],\\\"mapped\\\",[16687]],[[194905,194905],\\\"mapped\\\",[31296]],[[194906,194906],\\\"mapped\\\",[31306]],[[194907,194907],\\\"mapped\\\",[31311]],[[194908,194908],\\\"mapped\\\",[153980]],[[194909,194910],\\\"mapped\\\",[154279]],[[194911,194911],\\\"disallowed\\\"],[[194912,194912],\\\"mapped\\\",[16898]],[[194913,194913],\\\"mapped\\\",[154539]],[[194914,194914],\\\"mapped\\\",[31686]],[[194915,194915],\\\"mapped\\\",[31689]],[[194916,194916],\\\"mapped\\\",[16935]],[[194917,194917],\\\"mapped\\\",[154752]],[[194918,194918],\\\"mapped\\\",[31954]],[[194919,194919],\\\"mapped\\\",[17056]],[[194920,194920],\\\"mapped\\\",[31976]],[[194921,194921],\\\"mapped\\\",[31971]],[[194922,194922],\\\"mapped\\\",[32000]],[[194923,194923],\\\"mapped\\\",[155526]],[[194924,194924],\\\"mapped\\\",[32099]],[[194925,194925],\\\"mapped\\\",[17153]],[[194926,194926],\\\"mapped\\\",[32199]],[[194927,194927],\\\"mapped\\\",[32258]],[[194928,194928],\\\"mapped\\\",[32325]],[[194929,194929],\\\"mapped\\\",[17204]],[[194930,194930],\\\"mapped\\\",[156200]],[[194931,194931],\\\"mapped\\\",[156231]],[[194932,194932],\\\"mapped\\\",[17241]],[[194933,194933],\\\"mapped\\\",[156377]],[[194934,194934],\\\"mapped\\\",[32634]],[[194935,194935],\\\"mapped\\\",[156478]],[[194936,194936],\\\"mapped\\\",[32661]],[[194937,194937],\\\"mapped\\\",[32762]],[[194938,194938],\\\"mapped\\\",[32773]],[[194939,194939],\\\"mapped\\\",[156890]],[[194940,194940],\\\"mapped\\\",[156963]],[[194941,194941],\\\"mapped\\\",[32864]],[[194942,194942],\\\"mapped\\\",[157096]],[[194943,194943],\\\"mapped\\\",[32880]],[[194944,194944],\\\"mapped\\\",[144223]],[[194945,194945],\\\"mapped\\\",[17365]],[[194946,194946],\\\"mapped\\\",[32946]],[[194947,194947],\\\"mapped\\\",[33027]],[[194948,194948],\\\"mapped\\\",[17419]],[[194949,194949],\\\"mapped\\\",[33086]],[[194950,194950],\\\"mapped\\\",[23221]],[[194951,194951],\\\"mapped\\\",[157607]],[[194952,194952],\\\"mapped\\\",[157621]],[[194953,194953],\\\"mapped\\\",[144275]],[[194954,194954],\\\"mapped\\\",[144284]],[[194955,194955],\\\"mapped\\\",[33281]],[[194956,194956],\\\"mapped\\\",[33284]],[[194957,194957],\\\"mapped\\\",[36766]],[[194958,194958],\\\"mapped\\\",[17515]],[[194959,194959],\\\"mapped\\\",[33425]],[[194960,194960],\\\"mapped\\\",[33419]],[[194961,194961],\\\"mapped\\\",[33437]],[[194962,194962],\\\"mapped\\\",[21171]],[[194963,194963],\\\"mapped\\\",[33457]],[[194964,194964],\\\"mapped\\\",[33459]],[[194965,194965],\\\"mapped\\\",[33469]],[[194966,194966],\\\"mapped\\\",[33510]],[[194967,194967],\\\"mapped\\\",[158524]],[[194968,194968],\\\"mapped\\\",[33509]],[[194969,194969],\\\"mapped\\\",[33565]],[[194970,194970],\\\"mapped\\\",[33635]],[[194971,194971],\\\"mapped\\\",[33709]],[[194972,194972],\\\"mapped\\\",[33571]],[[194973,194973],\\\"mapped\\\",[33725]],[[194974,194974],\\\"mapped\\\",[33767]],[[194975,194975],\\\"mapped\\\",[33879]],[[194976,194976],\\\"mapped\\\",[33619]],[[194977,194977],\\\"mapped\\\",[33738]],[[194978,194978],\\\"mapped\\\",[33740]],[[194979,194979],\\\"mapped\\\",[33756]],[[194980,194980],\\\"mapped\\\",[158774]],[[194981,194981],\\\"mapped\\\",[159083]],[[194982,194982],\\\"mapped\\\",[158933]],[[194983,194983],\\\"mapped\\\",[17707]],[[194984,194984],\\\"mapped\\\",[34033]],[[194985,194985],\\\"mapped\\\",[34035]],[[194986,194986],\\\"mapped\\\",[34070]],[[194987,194987],\\\"mapped\\\",[160714]],[[194988,194988],\\\"mapped\\\",[34148]],[[194989,194989],\\\"mapped\\\",[159532]],[[194990,194990],\\\"mapped\\\",[17757]],[[194991,194991],\\\"mapped\\\",[17761]],[[194992,194992],\\\"mapped\\\",[159665]],[[194993,194993],\\\"mapped\\\",[159954]],[[194994,194994],\\\"mapped\\\",[17771]],[[194995,194995],\\\"mapped\\\",[34384]],[[194996,194996],\\\"mapped\\\",[34396]],[[194997,194997],\\\"mapped\\\",[34407]],[[194998,194998],\\\"mapped\\\",[34409]],[[194999,194999],\\\"mapped\\\",[34473]],[[195000,195000],\\\"mapped\\\",[34440]],[[195001,195001],\\\"mapped\\\",[34574]],[[195002,195002],\\\"mapped\\\",[34530]],[[195003,195003],\\\"mapped\\\",[34681]],[[195004,195004],\\\"mapped\\\",[34600]],[[195005,195005],\\\"mapped\\\",[34667]],[[195006,195006],\\\"mapped\\\",[34694]],[[195007,195007],\\\"disallowed\\\"],[[195008,195008],\\\"mapped\\\",[34785]],[[195009,195009],\\\"mapped\\\",[34817]],[[195010,195010],\\\"mapped\\\",[17913]],[[195011,195011],\\\"mapped\\\",[34912]],[[195012,195012],\\\"mapped\\\",[34915]],[[195013,195013],\\\"mapped\\\",[161383]],[[195014,195014],\\\"mapped\\\",[35031]],[[195015,195015],\\\"mapped\\\",[35038]],[[195016,195016],\\\"mapped\\\",[17973]],[[195017,195017],\\\"mapped\\\",[35066]],[[195018,195018],\\\"mapped\\\",[13499]],[[195019,195019],\\\"mapped\\\",[161966]],[[195020,195020],\\\"mapped\\\",[162150]],[[195021,195021],\\\"mapped\\\",[18110]],[[195022,195022],\\\"mapped\\\",[18119]],[[195023,195023],\\\"mapped\\\",[35488]],[[195024,195024],\\\"mapped\\\",[35565]],[[195025,195025],\\\"mapped\\\",[35722]],[[195026,195026],\\\"mapped\\\",[35925]],[[195027,195027],\\\"mapped\\\",[162984]],[[195028,195028],\\\"mapped\\\",[36011]],[[195029,195029],\\\"mapped\\\",[36033]],[[195030,195030],\\\"mapped\\\",[36123]],[[195031,195031],\\\"mapped\\\",[36215]],[[195032,195032],\\\"mapped\\\",[163631]],[[195033,195033],\\\"mapped\\\",[133124]],[[195034,195034],\\\"mapped\\\",[36299]],[[195035,195035],\\\"mapped\\\",[36284]],[[195036,195036],\\\"mapped\\\",[36336]],[[195037,195037],\\\"mapped\\\",[133342]],[[195038,195038],\\\"mapped\\\",[36564]],[[195039,195039],\\\"mapped\\\",[36664]],[[195040,195040],\\\"mapped\\\",[165330]],[[195041,195041],\\\"mapped\\\",[165357]],[[195042,195042],\\\"mapped\\\",[37012]],[[195043,195043],\\\"mapped\\\",[37105]],[[195044,195044],\\\"mapped\\\",[37137]],[[195045,195045],\\\"mapped\\\",[165678]],[[195046,195046],\\\"mapped\\\",[37147]],[[195047,195047],\\\"mapped\\\",[37432]],[[195048,195048],\\\"mapped\\\",[37591]],[[195049,195049],\\\"mapped\\\",[37592]],[[195050,195050],\\\"mapped\\\",[37500]],[[195051,195051],\\\"mapped\\\",[37881]],[[195052,195052],\\\"mapped\\\",[37909]],[[195053,195053],\\\"mapped\\\",[166906]],[[195054,195054],\\\"mapped\\\",[38283]],[[195055,195055],\\\"mapped\\\",[18837]],[[195056,195056],\\\"mapped\\\",[38327]],[[195057,195057],\\\"mapped\\\",[167287]],[[195058,195058],\\\"mapped\\\",[18918]],[[195059,195059],\\\"mapped\\\",[38595]],[[195060,195060],\\\"mapped\\\",[23986]],[[195061,195061],\\\"mapped\\\",[38691]],[[195062,195062],\\\"mapped\\\",[168261]],[[195063,195063],\\\"mapped\\\",[168474]],[[195064,195064],\\\"mapped\\\",[19054]],[[195065,195065],\\\"mapped\\\",[19062]],[[195066,195066],\\\"mapped\\\",[38880]],[[195067,195067],\\\"mapped\\\",[168970]],[[195068,195068],\\\"mapped\\\",[19122]],[[195069,195069],\\\"mapped\\\",[169110]],[[195070,195071],\\\"mapped\\\",[38923]],[[195072,195072],\\\"mapped\\\",[38953]],[[195073,195073],\\\"mapped\\\",[169398]],[[195074,195074],\\\"mapped\\\",[39138]],[[195075,195075],\\\"mapped\\\",[19251]],[[195076,195076],\\\"mapped\\\",[39209]],[[195077,195077],\\\"mapped\\\",[39335]],[[195078,195078],\\\"mapped\\\",[39362]],[[195079,195079],\\\"mapped\\\",[39422]],[[195080,195080],\\\"mapped\\\",[19406]],[[195081,195081],\\\"mapped\\\",[170800]],[[195082,195082],\\\"mapped\\\",[39698]],[[195083,195083],\\\"mapped\\\",[40000]],[[195084,195084],\\\"mapped\\\",[40189]],[[195085,195085],\\\"mapped\\\",[19662]],[[195086,195086],\\\"mapped\\\",[19693]],[[195087,195087],\\\"mapped\\\",[40295]],[[195088,195088],\\\"mapped\\\",[172238]],[[195089,195089],\\\"mapped\\\",[19704]],[[195090,195090],\\\"mapped\\\",[172293]],[[195091,195091],\\\"mapped\\\",[172558]],[[195092,195092],\\\"mapped\\\",[172689]],[[195093,195093],\\\"mapped\\\",[40635]],[[195094,195094],\\\"mapped\\\",[19798]],[[195095,195095],\\\"mapped\\\",[40697]],[[195096,195096],\\\"mapped\\\",[40702]],[[195097,195097],\\\"mapped\\\",[40709]],[[195098,195098],\\\"mapped\\\",[40719]],[[195099,195099],\\\"mapped\\\",[40726]],[[195100,195100],\\\"mapped\\\",[40763]],[[195101,195101],\\\"mapped\\\",[173568]],[[195102,196605],\\\"disallowed\\\"],[[196606,196607],\\\"disallowed\\\"],[[196608,262141],\\\"disallowed\\\"],[[262142,262143],\\\"disallowed\\\"],[[262144,327677],\\\"disallowed\\\"],[[327678,327679],\\\"disallowed\\\"],[[327680,393213],\\\"disallowed\\\"],[[393214,393215],\\\"disallowed\\\"],[[393216,458749],\\\"disallowed\\\"],[[458750,458751],\\\"disallowed\\\"],[[458752,524285],\\\"disallowed\\\"],[[524286,524287],\\\"disallowed\\\"],[[524288,589821],\\\"disallowed\\\"],[[589822,589823],\\\"disallowed\\\"],[[589824,655357],\\\"disallowed\\\"],[[655358,655359],\\\"disallowed\\\"],[[655360,720893],\\\"disallowed\\\"],[[720894,720895],\\\"disallowed\\\"],[[720896,786429],\\\"disallowed\\\"],[[786430,786431],\\\"disallowed\\\"],[[786432,851965],\\\"disallowed\\\"],[[851966,851967],\\\"disallowed\\\"],[[851968,917501],\\\"disallowed\\\"],[[917502,917503],\\\"disallowed\\\"],[[917504,917504],\\\"disallowed\\\"],[[917505,917505],\\\"disallowed\\\"],[[917506,917535],\\\"disallowed\\\"],[[917536,917631],\\\"disallowed\\\"],[[917632,917759],\\\"disallowed\\\"],[[917760,917999],\\\"ignored\\\"],[[918000,983037],\\\"disallowed\\\"],[[983038,983039],\\\"disallowed\\\"],[[983040,1048573],\\\"disallowed\\\"],[[1048574,1048575],\\\"disallowed\\\"],[[1048576,1114109],\\\"disallowed\\\"],[[1114110,1114111],\\\"disallowed\\\"]]\");\n\n/***/ }),\n\n/***/ 2357:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"assert\");\n\n/***/ }),\n\n/***/ 8614:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"events\");\n\n/***/ }),\n\n/***/ 5747:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"fs\");\n\n/***/ }),\n\n/***/ 8605:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"http\");\n\n/***/ }),\n\n/***/ 7211:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"https\");\n\n/***/ }),\n\n/***/ 1631:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"net\");\n\n/***/ }),\n\n/***/ 2087:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"os\");\n\n/***/ }),\n\n/***/ 5622:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"path\");\n\n/***/ }),\n\n/***/ 4213:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"punycode\");\n\n/***/ }),\n\n/***/ 2413:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"stream\");\n\n/***/ }),\n\n/***/ 4016:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"tls\");\n\n/***/ }),\n\n/***/ 8835:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"url\");\n\n/***/ }),\n\n/***/ 1669:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"util\");\n\n/***/ }),\n\n/***/ 8761:\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = require(\"zlib\");\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\tvar threw = true;\n/******/ \t\ttry {\n/******/ \t\t\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/ \t\t\tthrew = false;\n/******/ \t\t} finally {\n/******/ \t\t\tif(threw) delete __webpack_module_cache__[moduleId];\n/******/ \t\t}\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat */\n/******/ \t\n/******/ \t__webpack_require__.ab = __dirname + \"/\";/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(2932);\n/******/ })()\n;"
  },
  {
    "path": "pkg/runner/testdata/actions/node20/index.js",
    "content": "const core = require('@actions/core');\nconst github = require('@actions/github');\n\ntry {\n  // `who-to-greet` input defined in action metadata file\n  const nameToGreet = core.getInput('who-to-greet');\n  console.log(`Hello ${nameToGreet}!`);\n  const time = (new Date()).toTimeString();\n  core.setOutput(\"time\", time);\n  // Get the JSON webhook payload for the event that triggered the workflow\n  const payload = JSON.stringify(github.context.payload, undefined, 2)\n  console.log(`The event payload: ${payload}`);\n} catch (error) {\n  core.setFailed(error.message);\n}"
  },
  {
    "path": "pkg/runner/testdata/actions/node20/package.json",
    "content": "{\n  \"name\": \"node20\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"build\": \"ncc build index.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"@actions/core\": \"^1.2.6\",\n    \"@actions/github\": \"^4.0.0\"\n  },\n  \"devDependencies\": {\n    \"@vercel/ncc\": \"^0.24.1\"\n  },\n  \"engines\": {\n    \"node\": \">=20\"\n  }\n}\n"
  },
  {
    "path": "pkg/runner/testdata/actions-environment-and-context-tests/docker/Dockerfile",
    "content": "FROM alpine:3\n\nCOPY entrypoint.sh /entrypoint.sh\n\nENTRYPOINT [ \"/entrypoint.sh\" ]\n"
  },
  {
    "path": "pkg/runner/testdata/actions-environment-and-context-tests/docker/action.yml",
    "content": "name: 'Test'\ndescription: 'Test'\nruns:\n  using: 'docker'\n  image: 'Dockerfile'\n"
  },
  {
    "path": "pkg/runner/testdata/actions-environment-and-context-tests/docker/entrypoint.sh",
    "content": "#!/bin/sh\n\ncheckEnvVar() {\n\tname=$1\n\tvalue=$2\n\tallowEmpty=$3\n\n\tif [ -z \"$value\" ]; then\n\t\techo \"Missing environment variable: $name\"\n\t\texit 1\n\tfi\n\n\tif [ \"$allowEmpty\" != \"true\" ]; then\n\t\ttest=$(echo \"$value\" |cut -f 2 -d \"=\")\n\t\tif [ -z \"$test\" ]; then\n\t\t\techo \"Environment variable is empty: $name\"\n\t\t\texit 1\n\t\tfi\n\tfi\n\n\techo \"$value\"\n}\n\ncheckEnvVar \"GITHUB_ACTION\" \"$(env |grep \"GITHUB_ACTION=\")\" false\ncheckEnvVar \"GITHUB_ACTION_REPOSITORY\" \"$(env |grep \"GITHUB_ACTION_REPOSITORY=\")\" true\ncheckEnvVar \"GITHUB_ACTION_REF\" \"$(env |grep \"GITHUB_ACTION_REF=\")\" true\n"
  },
  {
    "path": "pkg/runner/testdata/actions-environment-and-context-tests/js/action.yml",
    "content": "name: 'Test'\ndescription: 'Test'\nruns:\n  using: 'node12'\n  main: 'index.js'\n"
  },
  {
    "path": "pkg/runner/testdata/actions-environment-and-context-tests/js/index.js",
    "content": "function checkEnvVar({ name, allowEmpty }) {\n  if (\n    process.env[name] === undefined ||\n    (allowEmpty === false && process.env[name] === \"\")\n  ) {\n    throw new Error(\n      `${name} is undefined` + (allowEmpty === false ? \" or empty\" : \"\")\n    );\n  }\n  console.log(`${name}=${process.env[name]}`);\n}\n\ncheckEnvVar({ name: \"GITHUB_ACTION\", allowEmpty: false });\ncheckEnvVar({ name: \"GITHUB_ACTION_REPOSITORY\", allowEmpty: true /* allows to be empty for local actions */ });\ncheckEnvVar({ name: \"GITHUB_ACTION_REF\", allowEmpty: true /* allows to be empty for local actions */ });\n"
  },
  {
    "path": "pkg/runner/testdata/actions-environment-and-context-tests/push.yml",
    "content": "name: actions-with-environment-and-context-tests\nrun-name: \"Actions with environment (env vars) and context (expression) tests\"\non: push\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: './actions-environment-and-context-tests/js'\n      - uses: './actions-environment-and-context-tests/docker'\n      - uses: 'nektos/act-test-actions/js@main'\n      - uses: 'nektos/act-test-actions/docker@main'\n      - uses: 'nektos/act-test-actions/docker-file@main'\n      - uses: 'nektos/act-test-actions/docker-relative-context/action@main'\n"
  },
  {
    "path": "pkg/runner/testdata/basic/push.yml",
    "content": "name: basic\non: push\n\nenv:\n  TEST: value\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - run: '[[ \"$(pwd)\" == \"${GITHUB_WORKSPACE}\" ]]'\n      - run: echo ${{ env.TEST }} | grep value\n      - run: env\n      - uses: docker://node:16-buster-slim\n        with:\n          somekey: ${{ env.TEST }}\n          args: echo ${INPUT_SOMEKEY} | grep somevalue\n      - run: ls\n      - run: echo 'hello world'\n      - run: echo ${GITHUB_SHA} >> $(dirname \"${GITHUB_WORKSPACE}\")/sha.txt\n      - run: cat $(dirname \"${GITHUB_WORKSPACE}\")/sha.txt | grep ${GITHUB_SHA}\n  build:\n    runs-on: ubuntu-latest\n    needs: [check]\n    steps:\n      - uses: actions/checkout@v2\n      - uses: ./actions/action1\n        with:\n          args: echo 'build'\n  test:\n    runs-on: ubuntu-latest\n    needs: [build]\n    steps:\n      - uses: docker://node:16-buster-slim\n        with:\n          args: env\n      - uses: docker://node:16-buster-slim\n        with:\n          entrypoint: /bin/echo\n          args: ${{github.event_name}}\n"
  },
  {
    "path": "pkg/runner/testdata/checkout/push.yml",
    "content": "name: checkout\non: push\n\njobs:\n  checkout:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n"
  },
  {
    "path": "pkg/runner/testdata/commands/push.yml",
    "content": "name: basic\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: TEST set-env\n        run: echo \"::set-env name=foo::bar\"\n      - name: TEST set-env (cont.)\n        run: echo $foo | grep bar\n\n      - name: TEST set-output\n        id: set_output\n        run: echo \"::set-output name=zoo::zar\"\n\n      - run: echo \"::add-path::/zip\"\n      - run: echo $PATH | grep /zip\n\n      - name: TEST conditional\n        if: steps.set_output.outputs.zoo\n        run: echo \"::set-env name=cond_env::foo\"\n      - name: TEST conditional (cont.)\n        run: echo $cond_env | grep foo\n\n      - name: TEST debug, warning, error\n        run: |\n          echo \"::debug file=app.js,line=100,col=20::Hello debug!\"\n          echo \"::warning file=app.js,line=100,col=20::Hello warning!\"\n          echo \"::error file=app.js,line=100,col=30::Hello error!\"\n\n      - name: TEST stop-commands\n        run: |\n          echo \"::stop-commands::my-end-token\" \n          echo \"::set-env name=foo::baz\"\n          echo $foo | grep bar\n          echo \"::my-end-token::\"\n          echo \"::set-env name=foo::baz\"\n      - name: TEST stop-commands (cont.)\n        run: echo $foo | grep baz\n"
  },
  {
    "path": "pkg/runner/testdata/composite-fail-with-output/push.yml",
    "content": "name: composite-fail-with-output\r\non: push\r\n\r\njobs:\r\n  test-for-output:\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - uses: actions/checkout@v2\r\n    - uses: ./actions/composite-fail-with-output\r\n      id: composite-fail-with-output\r\n      continue-on-error: true\r\n    - run: |\r\n        echo ${{steps.composite-fail-with-output.outputs.customoutput}}\r\n        exit ${{steps.composite-fail-with-output.outputs.customoutput == 'my-customoutput-green' && '0' || '1'}}"
  },
  {
    "path": "pkg/runner/testdata/container-hostname/push.yml",
    "content": "name: container-hostname\non: push\n\ndefaults:\n  run:\n    shell: bash\n\njobs:\n  with-hostname:\n    runs-on: ubuntu-latest\n    container:\n      image: node:16-buster-slim\n      options: \"--hostname my.host.local --user 100:101\"\n    steps:\n      - run: |\n          echo \"UID: $(id -u)\"\n          echo \"GID: $(id -g)\"\n          echo \"HOST: $(uname -n)\"\n          [[ \"$(id -u)\" == \"100\" ]] && [[ \"$(id -g)\" == \"101\" ]] && [[ \"$(uname -n)\" == \"my.host.local\" ]]\n\n  default-hostname:\n    runs-on: ubuntu-latest\n    container:\n      image: node:16-buster-slim\n    steps:\n      - run: |\n          echo \"UID: $(id -u)\"\n          echo \"GID: $(id -g)\"\n          echo \"HOST: $(uname -n)\"\n          [[ \"$(id -u)\" == \"0\" ]] && [[ \"$(id -g)\" == \"0\" ]] && [[ $(uname -n) ]] && [[ \"$(uname -n)\" != \"my.host.local\" ]]\n"
  },
  {
    "path": "pkg/runner/testdata/defaults-run/main.yaml",
    "content": "name: defaults-run\non:\n  - push\ndefaults:\n  run:\n    shell: sh\njobs:\n  without-defaults:\n    runs-on: ubuntu-latest\n    steps:\n    - run: echo $SHELL | grep -v bash || exit 1\n  with-defaults:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        shell: bash\n        working-directory: /tmp\n    steps:\n    - run: |\n        echo $SHELL | grep bash || exit 1\n        [ $(pwd) = /tmp ] || exit 2\n  override-in-step:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        shell: bash\n    steps:\n    - run: echo $SHELL | grep -v bash || exit 1\n      shell: sh\n"
  },
  {
    "path": "pkg/runner/testdata/dir with spaces/push.yml",
    "content": "---\njobs:\n  dir-with-spaces:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"$PWD\"\n'on': push\n"
  },
  {
    "path": "pkg/runner/testdata/do-not-leak-step-env-in-composite/push.yml",
    "content": "on: push\njobs:\n  _:\n    runs-on: ubuntu-latest\n    steps:\n    - run: |\n        runs:\n          using: composite\n          steps:\n          - run: exit 1\n            shell: bash\n            if: env.LEAK_ENV != 'val'\n      shell: cp {0} action.yml\n    - uses: ./\n      env:\n        LEAK_ENV: val\n    - run: exit 1\n      if: env.LEAK_ENV == 'val'"
  },
  {
    "path": "pkg/runner/testdata/docker-action-custom-path/push.yml",
    "content": "on: push\njobs:\n  _:\n    runs-on: ubuntu-latest\n    steps:\n    - run: |\n        FROM ubuntu:latest\n        ENV PATH=\"/opt/texlive/texdir/bin/x86_64-linuxmusl:${PATH}\"\n        ENV ORG_PATH=\"${PATH}\"\n        ENTRYPOINT [ \"bash\", \"-c\", \"echo \\\"PATH=$PATH\\\" && echo \\\"ORG_PATH=$ORG_PATH\\\" && [[ \\\"$PATH\\\" = \\\"$ORG_PATH\\\" ]]\" ]\n      shell: mv {0} Dockerfile\n    - uses: ./"
  },
  {
    "path": "pkg/runner/testdata/docker-action-host-env/action/Dockerfile",
    "content": "FROM debian:bullseye-slim\n\n# Install dependencies\nRUN apt-get update && apt-get install -y \\\n    curl \\\n    && apt-get clean\n\n# Copy the entrypoint script\nCOPY entrypoint.sh /entrypoint.sh\nRUN chmod +x /entrypoint.sh\n\n# Set the entrypoint\nENTRYPOINT [\"/entrypoint.sh\"]"
  },
  {
    "path": "pkg/runner/testdata/docker-action-host-env/action/action.yml",
    "content": "name: \"Hello World Docker Action\"\ndescription: \"A simple Docker action that prints Hello, World! and environment variables.\"\ninputs:\n  who-to-greet:\n    description: \"Who to greet\"\n    required: false\n    default: \"World\"\nruns:\n  using: \"docker\"\n  image: \"Dockerfile\"\n  args:\n    - ${{ inputs.who-to-greet }}"
  },
  {
    "path": "pkg/runner/testdata/docker-action-host-env/action/entrypoint.sh",
    "content": "#!/bin/bash\nset -e\n\n# Print a greeting\necho \"Hello, $1!\"\n\n# Print all environment variables\necho \"Environment Variables:\"\nenv\n\nls -la \"$PWD\"\nls -la \"$PWD/docker-action-host-env\"\n\nif [ -f \"$PWD/docker-action-host-env/Dockerfile\" ]; then\n  echo \"Dockerfile exists in workspace.\"\nelse\n  echo \"Dockerfile does not exist in workspace.\"\nfi\n"
  },
  {
    "path": "pkg/runner/testdata/docker-action-host-env/push.yml",
    "content": "name: Hello World Docker Action Workflow\n\non: [push]\n\njobs:\n  hello_world_job:\n    runs-on: self-hosted\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Run Hello World Docker Action\n        uses: ./docker-action-host-env/action\n        with:\n          who-to-greet: \"GitHub\"\n"
  },
  {
    "path": "pkg/runner/testdata/ensure-post-steps/action-composite/action.yml",
    "content": "name: \"action composite\"\ndescription: \"action composite\"\nruns:\n  using: composite\n  steps:\n    # second post action should fail if executed (we do check on the exit code)\n    - uses: ./ensure-post-steps/action-post/\n      with:\n        fail: \"true\"\n    - uses: ./ensure-post-steps/action-post/\n"
  },
  {
    "path": "pkg/runner/testdata/ensure-post-steps/action-post/action.yml",
    "content": "name: \"action post\"\ndescription: \"action post\"\ninputs:\n  fail:\n    description: \"true if this should fail\"\n    required: false\n    default: \"false\"\nruns:\n  using: node16\n  main: \"./main.js\"\n  post: \"./post.js\"\n"
  },
  {
    "path": "pkg/runner/testdata/ensure-post-steps/action-post/main.js",
    "content": ""
  },
  {
    "path": "pkg/runner/testdata/ensure-post-steps/action-post/post.js",
    "content": "if (process.env[\"INPUT_FAIL\"] === \"true\") {\n  process.exit(1);\n}\n"
  },
  {
    "path": "pkg/runner/testdata/ensure-post-steps/push.yml",
    "content": "name: test\non: push\njobs:\n  second-post-step-should-fail:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: ./ensure-post-steps/action-composite/\n"
  },
  {
    "path": "pkg/runner/testdata/env-and-path/push.yaml",
    "content": "name: env-and-path\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: \"Append to $GITHUB_PATH\"\n        run: |\n          echo \"$HOME/someFolder\" >> $GITHUB_PATH\n      - name: \"Append some more to $GITHUB_PATH\"\n        run: |\n          echo \"$HOME/someOtherFolder\" >> $GITHUB_PATH\n      - name: \"Check PATH\"\n        run: |\n          echo \"${PATH}\"\n          if [[ ! \"${PATH}\" =~ .*\"$HOME/\"someOtherFolder.*\"$HOME/\"someFolder.* ]]; then\n            echo \"${PATH} doesn't match .*someOtherFolder.*someFolder.*\"\n            exit 1\n          fi\n      - name: \"Prepend\"\n        run: |\n          if ls | grep -q 'called ls' ; then\n            echo 'ls was overridden already?'\n            exit 2\n          fi\n          path_add=$(mktemp -d)\n          cat > $path_add/ls <<LS\n          #!/bin/sh\n          echo 'called ls'\n          LS\n          chmod +x $path_add/ls\n          echo $path_add >> $GITHUB_PATH\n      - name: \"Verify prepend\"\n        run: |\n          if ! ls | grep -q 'called ls' ; then\n            echo 'ls was not overridden'\n            exit 2\n          fi\n      - name: \"Write single line env to $GITHUB_ENV\"\n        run: |\n          echo \"KEY=value\" >> $GITHUB_ENV\n      - name: \"Check single line env\"\n        run: |\n          if [[ \"${KEY}\" != \"value\" ]]; then\n            echo \"${KEY} doesn't == 'value'\"\n            exit 1\n          fi\n      - name: \"Write single line env with more than one 'equals' signs to $GITHUB_ENV\"\n        run: |\n          echo \"KEY=value=anothervalue\" >> $GITHUB_ENV\n      - name: \"Check single line env\"\n        run: |\n          if [[ \"${KEY}\" != \"value=anothervalue\" ]]; then\n            echo \"${KEY} doesn't == 'value=anothervalue'\"\n            exit 1\n          fi\n      - name: \"Write multiline env to $GITHUB_ENV\"\n        run: |\n          echo 'KEY2<<EOF' >> $GITHUB_ENV\n                echo value2 >> $GITHUB_ENV\n                echo 'EOF' >> $GITHUB_ENV\n      - name: \"Check multiline line env\"\n        run: |\n          if [[ \"${KEY2}\" != \"value2\" ]]; then\n            echo \"${KEY2} doesn't == 'value'\"\n            exit 1\n          fi\n      - name: \"Write multiline env with UUID to $GITHUB_ENV\"\n        run: |\n          echo 'KEY3<<ghadelimiter_b8273c6d-d535-419a-a010-b0aaac240e36' >> $GITHUB_ENV\n                echo value3 >> $GITHUB_ENV\n                echo 'ghadelimiter_b8273c6d-d535-419a-a010-b0aaac240e36' >> $GITHUB_ENV\n      - name: \"Check multiline env with UUID to $GITHUB_ENV\"\n        run: |\n          if [[ \"${KEY3}\" != \"value3\" ]]; then\n            echo \"${KEY3} doesn't == 'value3'\"\n            exit 1\n          fi\n"
  },
  {
    "path": "pkg/runner/testdata/environment-files/push.yaml",
    "content": "name: environment-files\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: \"Append to $GITHUB_PATH\"\n        run: |\n          echo \"$HOME/someFolder\" >> $GITHUB_PATH\n      - name: \"Append some more to $GITHUB_PATH\"\n        run: |\n          echo \"$HOME/someOtherFolder\" >> $GITHUB_PATH\n      - name: \"Check PATH\"\n        run: |\n          echo \"${PATH}\"\n          if [[ ! \"${PATH}\" =~ .*\"$HOME/\"someOtherFolder.*\"$HOME/\"someFolder.* ]]; then\n            echo \"${PATH} doesn't match .*someOtherFolder.*someFolder.*\"\n            exit 1\n          fi\n      - name: \"Prepend\"\n        run: |\n          if ls | grep -q 'called ls' ; then\n            echo 'ls was overridden already?'\n            exit 2\n          fi\n          path_add=$(mktemp -d)\n          cat > $path_add/ls <<LS\n          #!/bin/sh\n          echo 'called ls'\n          LS\n          chmod +x $path_add/ls\n          echo $path_add >> $GITHUB_PATH\n      - name: \"Verify prepend\"\n        run: |\n          if ! ls | grep -q 'called ls' ; then\n            echo 'ls was not overridden'\n            exit 2\n          fi\n      - name: \"Write single line env to $GITHUB_ENV\"\n        run: |\n          echo \"KEY=value\" >> $GITHUB_ENV\n      - name: \"Check single line env\"\n        run: |\n          if [[ \"${KEY}\" != \"value\" ]]; then\n            echo \"${KEY} doesn't == 'value'\"\n            exit 1\n          fi\n      - name: \"Write single line env with more than one 'equals' signs to $GITHUB_ENV\"\n        run: |\n          echo \"KEY=value=anothervalue\" >> $GITHUB_ENV\n      - name: \"Check single line env\"\n        run: |\n          if [[ \"${KEY}\" != \"value=anothervalue\" ]]; then\n            echo \"${KEY} doesn't == 'value=anothervalue'\"\n            exit 1\n          fi\n      - name: \"Write multiline env to $GITHUB_ENV\"\n        run: |\n          echo 'KEY2<<EOF' >> $GITHUB_ENV\n          echo value2 >> $GITHUB_ENV\n          echo 'EOF' >> $GITHUB_ENV\n      - name: \"Check multiline line env\"\n        run: |\n          if [[ \"${KEY2}\" != \"value2\" ]]; then\n            echo \"${KEY2} doesn't == 'value'\"\n            exit 1\n          fi\n      - name: \"Write multiline env with UUID to $GITHUB_ENV\"\n        run: |\n          echo 'KEY3<<ghadelimiter_b8273c6d-d535-419a-a010-b0aaac240e36' >> $GITHUB_ENV\n          echo value3 >> $GITHUB_ENV\n          echo 'ghadelimiter_b8273c6d-d535-419a-a010-b0aaac240e36' >> $GITHUB_ENV\n      - name: \"Check multiline env with UUID to $GITHUB_ENV\"\n        run: |\n          if [[ \"${KEY3}\" != \"value3\" ]]; then\n            echo \"${KEY3} doesn't == 'value3'\"\n            exit 1\n          fi\n      - name: \"Write single line output to $GITHUB_OUTPUT\"\n        id: write-single-output\n        run: |\n          echo \"KEY=value\" >> $GITHUB_OUTPUT\n      - name: \"Check single line output\"\n        run: |\n          if [[ \"${{ steps.write-single-output.outputs.KEY }}\" != \"value\" ]]; then\n            echo \"${{ steps.write-single-output.outputs.KEY }} doesn't == 'value'\"\n            exit 1\n          fi\n      - name: \"Write multiline output to $GITHUB_OUTPUT\"\n        id: write-multi-output\n        run: |\n          echo 'KEY2<<EOF' >> $GITHUB_OUTPUT\n          echo value2 >> $GITHUB_OUTPUT\n          echo 'EOF' >> $GITHUB_OUTPUT\n      - name: \"Check multiline output\"\n        run: |\n          if [[ \"${{ steps.write-multi-output.outputs.KEY2 }}\" != \"value2\" ]]; then\n            echo \"${{ steps.write-multi-output.outputs.KEY2 }} doesn't == 'value2'\"\n            exit 1\n          fi"
  },
  {
    "path": "pkg/runner/testdata/environment-files-parser-bug/push.yaml",
    "content": "on: push\njobs:\n  _:\n    runs-on: ubuntu-latest\n    steps:\n    - run: |\n        echo \"test<<World\" > $GITHUB_ENV\n        echo \"x=Thats really Weird\" >> $GITHUB_ENV\n        echo \"World\" >> $GITHUB_ENV\n    - if: env.test != 'x=Thats really Weird'\n      run: exit 1\n    - if: env.x == 'Thats really Weird' # This assert is triggered by the broken impl of act\n      run: exit 1"
  },
  {
    "path": "pkg/runner/testdata/environment-variables/push.yml",
    "content": "name: environment variables\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Test on job level\n        run: |\n          echo \\$UPPER=$UPPER\n          echo \\$upper=$upper\n          echo \\$LOWER=$LOWER\n          echo \\$lower=$lower\n          [[ \"$UPPER\" = \"UPPER\" ]] || exit 1\n          [[ \"$upper\" = \"\" ]] || exit 1\n          [[ \"$LOWER\" = \"\" ]] || exit 1\n          [[ \"$lower\" = \"lower\" ]] || exit 1\n      - name: Test on step level\n        run: |\n          echo \\$UPPER=$UPPER\n          echo \\$upper=$upper\n          echo \\$LOWER=$LOWER\n          echo \\$lower=$lower\n          [[ \"$UPPER\" = \"upper\" ]] || exit 1\n          [[ \"$upper\" = \"\" ]] || exit 1\n          [[ \"$LOWER\" = \"\" ]] || exit 1\n          [[ \"$lower\" = \"LOWER\" ]] || exit 1\n        env:\n          UPPER: upper\n          lower: LOWER\n    env:\n      UPPER: UPPER\n      lower: lower\n"
  },
  {
    "path": "pkg/runner/testdata/evalenv/push.yml",
    "content": "name: CI\n\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    env:\n      BUILD_DIR: ${{ github.workspace }}/build\n    steps:\n      - name: Dump\n        run: |\n          echo \"$BUILD_DIR\"\n          echo \"$EXPECTED_BUILD_DIR\"\n          echo \"$GITHUB_WORKSPACE/build\"\n        env:\n          EXPECTED_BUILD_DIR: ${{ github.workspace }}/build\n      - name: Test\n        run: |\n          [ \"$BUILD_DIR\" = \"$EXPECTED_BUILD_DIR\" ] && [ \"$BUILD_DIR\" = \"$GITHUB_WORKSPACE/build\" ]\n        env:\n          EXPECTED_BUILD_DIR: ${{ github.workspace }}/build\n"
  },
  {
    "path": "pkg/runner/testdata/evalmatrix/push.yml",
    "content": "on: push\r\njobs:\r\n  evalm:\r\n    strategy:\r\n      matrix: |-\r\n        ${{fromJson('\r\n          {\r\n            \"A\": [ \"A\", \"B\" ]\r\n          }\r\n        ')}}\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - name: Check if the matrix key A exists\r\n      run: |\r\n        echo $MATRIX\r\n        exit ${{matrix.A && '0' || '1'}}\r\n      env:\r\n        MATRIX: ${{toJSON(matrix)}}\r\n  _additionalInclude_0:\r\n    strategy:\r\n      matrix:\r\n        include:\r\n        - def: val\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - name: Check if the matrix key A exists\r\n      run: |\r\n        echo $MATRIX\r\n        exit ${{matrix.def == 'val' && '0' || '1'}}\r\n      env:\r\n        MATRIX: ${{toJSON(matrix)}}\r\n    - run: |\r\n        echo \"::set-output name=result::success\"\r\n      id: result\r\n    outputs:\r\n      result: ${{ steps.result.outputs.result }}\r\n  _additionalInclude_1:\r\n    needs: _additionalInclude_0\r\n    if: always()\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - name: Check if the matrix key A exists\r\n      run: |\r\n        echo $MATRIX\r\n        exit ${{needs._additionalInclude_0.outputs.result == 'success' && '0' || '1'}}\r\n  _additionalProperties_0:\r\n    strategy:\r\n      matrix:\r\n        x:\r\n        - 0\r\n        y:\r\n        - 0\r\n        z:\r\n        - 0\r\n        include:\r\n        - def: val\r\n          z: 0\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - name: Check if the matrix key A exists\r\n      run: |\r\n        echo $MATRIX\r\n        exit ${{matrix.def == 'val' && matrix.x == 0 && matrix.y == 0 && matrix.z == 0 && '0' || '1'}}\r\n      env:\r\n        MATRIX: ${{toJSON(matrix)}}\r\n    - run: |\r\n        echo \"::set-output name=result::success\"\r\n      id: result\r\n    outputs:\r\n      result: ${{ steps.result.outputs.result }}\r\n  _additionalProperties_1:\r\n    needs: _additionalProperties_0\r\n    if: always()\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - name: Check if the matrix key A exists\r\n      run: |\r\n        echo $MATRIX\r\n        exit ${{needs._additionalProperties_0.outputs.result == 'success' && '0' || '1'}}\r\n"
  },
  {
    "path": "pkg/runner/testdata/evalmatrix-merge-array/push.yml",
    "content": "on: push\r\njobs:\r\n  a:\r\n    strategy:\r\n      matrix:\r\n        a:\r\n        - env:\r\n              key1: ${{'val'}}1\r\n        - ${{fromJSON('[{\"env\":{\"key2\":\"val2\"}},{\"env\":{\"key3\":\"val3\"}}]')}}\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - run: exit ${{ (matrix.a.env.key2 == 'val2' || matrix.a.env.key1 == 'val1' || matrix.a.env.key3 == 'val3' ) && '0' || '1' }}"
  },
  {
    "path": "pkg/runner/testdata/evalmatrix-merge-map/push.yml",
    "content": "on: push\r\njobs:\r\n  a:\r\n    strategy:\r\n      matrix:\r\n        a:\r\n        - env:\r\n              key1: val1\r\n              ${{insert}}:\r\n                 key2: val2\r\n              ${{ insert }}: ${{fromJSON('{\"key3\":\"val3\"}')}}\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - run: exit ${{ (matrix.a.env.key2 == 'val2' && matrix.a.env.key1 == 'val1' && matrix.a.env.key3 == 'val3' ) && '0' || '1' }}"
  },
  {
    "path": "pkg/runner/testdata/evalmatrixneeds/push.yml",
    "content": "on: push\r\njobs:\r\n  prepare:\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - run: |\r\n        echo '::set-output name=matrix::{\"package\": [\"a\", \"b\"]}'\r\n      id: r1\r\n    outputs:\r\n      matrix: ${{steps.r1.outputs.matrix}}\r\n  evalm:\r\n    needs:\r\n    - prepare\r\n    strategy:\r\n      matrix: |-\r\n        ${{fromJson(needs.prepare.outputs.matrix)}}\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - name: Check if the matrix key package exists\r\n      run: |\r\n        echo $MATRIX\r\n        exit ${{matrix.package && '0' || '1'}}\r\n      env:\r\n        MATRIX: ${{toJSON(matrix)}}"
  },
  {
    "path": "pkg/runner/testdata/evalmatrixneeds2/push.yml",
    "content": "on: push\r\njobs:\r\n  prepare:\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - run: |\r\n        echo '::set-output name=matrix::[\"a\", \"b\"]'\r\n      id: r1\r\n    outputs:\r\n      matrix: ${{steps.r1.outputs.matrix}}\r\n      helix: steady\r\n  evalm:\r\n    needs:\r\n    - prepare\r\n    strategy:\r\n      matrix: \r\n        ${{needs.prepare.outputs.helix}}: |-\r\n          ${{fromJson(needs.prepare.outputs.matrix)}}\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n    - name: Check if the matrix key doesn't ends up unevaluated\r\n      run: |\r\n        echo $MATRIX\r\n        exit ${{matrix['${{needs.prepare.outputs.helix}}'] && '1' || '0'}}\r\n      env:\r\n        MATRIX: ${{toJSON(matrix)}}\r\n    - name: Check if the evaluated matrix key contains a value\r\n      run: |\r\n        exit ${{matrix[needs.prepare.outputs.helix] && '0' || '1'}}\r\n"
  },
  {
    "path": "pkg/runner/testdata/fail/push.yml",
    "content": "name: fail\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    container:\n      image: node:16-buster-slim\n      env:\n        TEST_ENV: test-value\n    steps:\n      - run: echo ${TEST_ENV} | grep bazooka\n"
  },
  {
    "path": "pkg/runner/testdata/if-env-act/push.yml",
    "content": "name: if-env-act-test\r\non: push\r\n\r\njobs:\r\n  if_env_test:\r\n    name: Test if env.ACT matching\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n      # Should RUN, since we are running in act\r\n      - name: Positive env.ACT match\r\n        if: ${{ env.ACT }}\r\n        shell: bash\r\n        run: |\r\n          echo \"This workflow is run using act, continue!\"\r\n          echo \"ACT: $ACT\"\r\n          exit 0\r\n\r\n      # Should SKIP, since we are running in act\r\n      - name: Negative env.ACT match\r\n        if: ${{ !env.ACT }}\r\n        shell: bash\r\n        run: |\r\n          echo \"This should be skipped since this workflow is run using act, fail!\"\r\n          echo \"ACT: $ACT\"\r\n          exit 1"
  },
  {
    "path": "pkg/runner/testdata/if-expressions/push.yml",
    "content": "on: push\njobs:\n  mytest:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      # - run: exit 1\n      - uses: ./\n        if: failure()\n      - run: echo Success\n        shell: bash\n      - run: echo Success\n        if: success()\n        shell: bash\n      - run: exit 1\n        shell: bash\n      - run: echo \"Shouldn't run\"\n        if: success()\n        shell: bash\n      - run: echo \"Shouldn't run2\"\n        shell: bash\n      - run: echo expected to run\n        if: failure()\n        shell: bash\n  next:\n    needs: mytest\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n"
  },
  {
    "path": "pkg/runner/testdata/input-from-cli/input.yml",
    "content": "on:\n  workflow_dispatch:\n    inputs:\n      NAME:\n        description: \"A random input name for the workflow\"\n        type: string\n        required: true\n      SOME_VALUE:\n        description: \"Some other input to pass\"\n        type: string\n        required: true\n\njobs:\n  test:\n    name: Test\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Test with inputs\n        run: |\n          [ -z \"${{ github.event.inputs.SOME_INPUT }}\" ] && exit 1 || exit 0\n"
  },
  {
    "path": "pkg/runner/testdata/inputs-via-env-context/action/action.yml",
    "content": "inputs:\n  test-env-input: {}\nruns:\n  using: composite\n  steps:\n  - run: |\n      exit ${{ inputs.test-env-input == env.test-env-input && '0' || '1'}}\n    shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/inputs-via-env-context/push.yml",
    "content": "on: push\njobs:\n  test-inputs-via-env-context:\n    runs-on: self-hosted\n    steps:\n    - uses: actions/checkout@v3\n    - uses: ./inputs-via-env-context/action\n      with:\n        test-env-input: ${{ env.test-env-input }}\n      env:\n        test-env-input: ${{ github.event_name }}/${{ github.run_id }}\n    - run: |\n        exit ${{ env.test-env-input == format('{0}/{1}', github.event_name, github.run_id) && '0' || '1' }}\n      env:\n        test-env-input: ${{ github.event_name }}/${{ github.run_id }}"
  },
  {
    "path": "pkg/runner/testdata/issue-104/main.yaml",
    "content": "name: Test stuff\n\non:\n  - push\n\njobs:\n  build:\n    name: Testing Testing\n    runs-on: ubuntu-latest\n    steps:\n\n    - name: hello\n      uses: actions/hello-world-docker-action@v1\n      with:\n        who-to-greet: \"World\"\n"
  },
  {
    "path": "pkg/runner/testdata/issue-1195/push.yml",
    "content": "on: push\n\nenv:\n  variable: \"${{ github.repository_owner }}\"\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - name: print env.variable\n        run: |\n          echo ${{ env.variable }}\n          exit ${{ (env.variable == 'nektos') && '0' || '1'}}\n"
  },
  {
    "path": "pkg/runner/testdata/issue-122/main.yaml",
    "content": "name: Checkout\n\non: push\n\njobs:\n\n  test:\n    name: Test\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n      with:\n        path: test-subdir1\n    - run: grep \"Checkout\" test-subdir1/issue-122/main.yaml\n    - uses: actions/checkout@v2\n      with:\n        repository: actions/checkout\n        path: test-subdir2\n    - run: grep \"Checkout\" test-subdir2/action.yml\n"
  },
  {
    "path": "pkg/runner/testdata/issue-141/main.yaml",
    "content": "name: \"Create cluster using KinD\"\non: push\n\njobs:\n  kind:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@master\n    - uses: engineerd/setup-kind@v0.3.0\n    - name: Testing\n      run: |\n        kubectl cluster-info\n        kubectl get pods -n kube-system\n"
  },
  {
    "path": "pkg/runner/testdata/issue-1595/missing.yml",
    "content": "name: missing\non: push\n\njobs:\n  second:\n    runs-on: ubuntu-latest\n    needs: first\n    steps:\n      - run: echo How did you get here?\n        shell: bash\n\n  standalone:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo Hello world\n        shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/issue-1595/no-event.yml",
    "content": "name: no event\n\njobs:\n  stuck:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo How did you get here?\n        shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/issue-1595/no-first.yml",
    "content": "name: no first\non: push\n\njobs:\n  second:\n    runs-on: ubuntu-latest\n    needs: first\n    steps:\n      - run: echo How did you get here?\n        shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/issue-597/spelling.yaml",
    "content": "name: issue-597\non: push\n\n\njobs:\n  my_first_job:\n\n    runs-on: ubuntu-latest\n    steps:\n      - name: My first false step\n        if: \"endsWith('Should not', 'o1')\"\n        uses: actions/checkout@v2.0.0\n        with:\n          ref: refs/pull/${{github.event.pull_request.number}}/merge\n          fetch-depth: 5\n      - name: My first true step\n        if: ${{endsWith('Hello world', 'ld')}}\n        uses: actions/hello-world-javascript-action@main\n        with:\n          who-to-greet: \"Renst the Octocat\"\n      - name: My second false step\n        if: \"endsWith('Should not evaluate', 'o2')\"\n        uses: actions/checkout@v2.0.0\n        with:\n          ref: refs/pull/${{github.event.pull_request.number}}/merge\n          fetch-depth: 5\n      - name: My third false step\n        if: ${{endsWith('Should not evaluate', 'o3')}}\n        uses: actions/checkout@v2.0.0\n        with:\n          ref: refs/pull/${{github.event.pull_request.number}}/merge\n          fetch-depth: 5\n"
  },
  {
    "path": "pkg/runner/testdata/issue-598/spelling.yml",
    "content": "name: issue-598\non: push\n  \n\njobs:\n  my_first_job:\n    \n    runs-on: ubuntu-latest\n    steps:\n      - name: My first false step\n        if: \"endsWith('Hello world', 'o1')\"\n        uses: actions/hello-world-javascript-action@main\n        with:\n          who-to-greet: 'Mona the Octocat'\n      - name: My first true step\n        if: \"!endsWith('Hello world', 'od')\"\n        uses: actions/hello-world-javascript-action@main\n        with:\n          who-to-greet: \"Renst the Octocat\"\n      - name: My second false step\n        if: \"endsWith('Hello world', 'o2')\"\n        uses: actions/hello-world-javascript-action@main\n        with:\n          who-to-greet: 'Act the Octocat'\n      - name: My third false step\n        if: \"endsWith('Hello world', 'o2')\"\n        uses: actions/hello-world-javascript-action@main\n        with:\n          who-to-greet: 'Git the Octocat'\n           \n           "
  },
  {
    "path": "pkg/runner/testdata/job-container/push.yml",
    "content": "name: job-container\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    container:\n      image: node:16-buster-slim\n      env:\n        TEST_ENV: test-value\n    steps:\n      - run: echo ${TEST_ENV} | grep test-value\n\n  test2:\n    runs-on: ubuntu-latest\n    container: node:16-buster-slim\n    steps:\n      - run: echo ${TEST_ENV} | grep test-value\n        env:\n          TEST_ENV: test-value\n"
  },
  {
    "path": "pkg/runner/testdata/job-container-invalid-credentials/push.yml",
    "content": "name: job-container-invalid-credentials\non: push\n\njobs:\n  fail-on-invalid-credentials:\n    runs-on: ubuntu-latest\n    container:\n      image: node:16-buster-slim\n      credentials:\n        username: \"user\"\n        password: \"\" # Empty password caused a crash in jobexecutor\n    steps:\n      - run: exit 0\n"
  },
  {
    "path": "pkg/runner/testdata/job-container-non-root/push.yml",
    "content": "name: job-container\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    container:\n      image: catthehacker/ubuntu:runner-latest # image with user 'runner:runner' built on tag 'act-latest'\n    steps:\n      - run: echo PASS\n"
  },
  {
    "path": "pkg/runner/testdata/job-needs-context-contains-result/push.yml",
    "content": "on:\n  push:\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - run: exit 0\n  assert:\n    needs: test\n    if: |\n      ( always() && !cancelled() ) && (\n      ( needs.test.result != 'success' || !success() ) )\n    runs-on: ubuntu-latest\n    steps:\n    - run: exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/job-nil-step/push.yml",
    "content": "on: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    -\n    - run: exit 0\n"
  },
  {
    "path": "pkg/runner/testdata/job-status-check/push.yml",
    "content": "on: push\njobs:\n  fail:\n    runs-on: ubuntu-latest\n    steps:\n    - run: exit 1\n  suc1:\n    if: success() || failure()\n    needs:\n    - fail\n    runs-on: ubuntu-latest\n    steps:\n    - run: exit 0\n  suc2:\n    if: success() || failure()\n    needs:\n    - fail\n    runs-on: ubuntu-latest\n    steps:\n    - run: exit 0\n  next:\n    needs:\n    - suc1\n    - suc2\n    runs-on: ubuntu-latest\n    steps:\n    - run: echo should never reach here\n    - run: exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/local-action-docker-url/push.yml",
    "content": "name: local-action-docker-url\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./actions/docker-url\n"
  },
  {
    "path": "pkg/runner/testdata/local-action-dockerfile/push.yml",
    "content": "name: local-action-dockerfile\non: push\ndefaults:\n  run:\n    shell: bash\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./actions/docker-local\n      id: dockerlocal\n      with:\n        who-to-greet: 'Mona the Octocat'\n    - run: '[[ \"${{ env.SOMEVAR }}\" == \"Mona the Octocat\" ]]'\n    - run: '[ \"${SOMEVAR}\" = \"Not Mona\" ] || exit 1'\n      env:\n        SOMEVAR: 'Not Mona'\n    - run: '[[ \"${{ steps.dockerlocal.outputs.whoami }}\" == \"Mona the Octocat\" ]]'\n    # Test if overriding args doesn't leak inputs\n    - uses: ./actions/docker-local-noargs\n      with:\n        args: ${{format('\"{0}\"', 'Mona is not the Octocat') }}\n        who-to-greet: 'Mona the Octocat'\n    - run: '[[ \"${{ env.SOMEVAR }}\" == \"Mona is not the Octocat\" ]]'\n    - uses: ./localdockerimagetest_\n"
  },
  {
    "path": "pkg/runner/testdata/local-action-js/push.yml",
    "content": "name: local-action-node12\non: push\n\njobs:\n  test-node12:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./actions/node12\n      with:\n        who-to-greet: 'Mona the Octocat'\n\n  test-node16:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./actions/node16\n      with:\n        who-to-greet: 'Mona the Octocat'\n  \n  test-node20:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./actions/node20\n      with:\n        who-to-greet: 'Mona the Octocat'\n"
  },
  {
    "path": "pkg/runner/testdata/local-action-via-composite-dockerfile/action/action.yml",
    "content": "inputs:\n  who-to-greet:\n    default: 'Mona the Octocat'\nruns:\n  using: composite\n  steps:\n  # Test if GITHUB_ACTION_PATH is set correctly before all steps\n  - run: stat $GITHUB_ACTION_PATH/../push.yml\n    shell: bash\n  - run: stat $GITHUB_ACTION_PATH/action.yml\n    shell: bash\n  - run: '[[ \"$GITHUB_ACTION_REPOSITORY\" == \"\" ]] && [[ \"$GITHUB_ACTION_REF\" == \"\" ]]'\n    shell: bash\n  - uses: ./actions/docker-local\n    id: dockerlocal\n    with:\n      who-to-greet: ${{inputs.who-to-greet}}\n  - run: '[[ \"${{ env.SOMEVAR }}\" == \"${{inputs.who-to-greet}}\" ]]'\n    shell: bash\n  - run: '[ \"${SOMEVAR}\" = \"Not Mona\" ] || exit 1'\n    shell: bash\n    env:\n      SOMEVAR: 'Not Mona'\n  - run: '[[ \"${{ steps.dockerlocal.outputs.whoami }}\" == \"${{inputs.who-to-greet}}\" ]]'\n    shell: bash\n  # Test if overriding args doesn't leak inputs\n  - uses: ./actions/docker-local-noargs\n    with:\n      args: ${{format('\"{0}\"', 'Mona is not the Octocat') }}\n      who-to-greet: ${{inputs.who-to-greet}}\n  - run: '[[ \"${{ env.SOMEVAR }}\" == \"Mona is not the Octocat\" ]]'\n    shell: bash\n  - uses: ./localdockerimagetest_\n  # Also test a remote docker action here\n  - uses: actions/hello-world-docker-action@v1\n    with:\n      who-to-greet: 'Mona the Octocat'\n  # Test if GITHUB_ACTION_PATH is set correctly after all steps\n  - run: stat $GITHUB_ACTION_PATH/../push.yml\n    shell: bash\n  - run: stat $GITHUB_ACTION_PATH/action.yml\n    shell: bash\n  - run: '[[ \"$GITHUB_ACTION_REPOSITORY\" == \"\" ]] && [[ \"$GITHUB_ACTION_REF\" == \"\" ]]'\n    shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/local-action-via-composite-dockerfile/push.yml",
    "content": "name: local-action-dockerfile\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./local-action-via-composite-dockerfile/action"
  },
  {
    "path": "pkg/runner/testdata/local-remote-action-overrides/config/config.yml",
    "content": "local-repositories:\n  https://github.com/nektos/test-override@a: testdata/actions/node20\n  nektos/test-override@b: testdata/actions/node16"
  },
  {
    "path": "pkg/runner/testdata/local-remote-action-overrides/push.yml",
    "content": "name: basic\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: nektos/test-override@a\n      - uses: nektos/test-override@b"
  },
  {
    "path": "pkg/runner/testdata/localdockerimagetest_/Dockerfile",
    "content": "FROM ubuntu:latest\nCMD echo Hello\n"
  },
  {
    "path": "pkg/runner/testdata/mask-values/composite/action.yml",
    "content": "name: composite\ndescription: composite\n\nruns:\n  using: composite\n  steps:\n    - run: echo \"secret value\"\n      shell: bash\n    - run: echo \"::add-mask::$(echo \"abc\" | base64)\"\n      shell: bash\n    - run: echo \"abc\" | base64\n      shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/mask-values/push.yml",
    "content": "name: mask-values\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - run: echo \"::add-mask::secret value\"\n      - run: echo \"secret value\"\n      - uses: ./mask-values/composite\n      - run: echo \"YWJjCg==\"\n"
  },
  {
    "path": "pkg/runner/testdata/matrix/push.yml",
    "content": "name: matrix\non: push\n\njobs:\n  build:\n    name: PHP ${{ matrix.os }} ${{ matrix.node}}\n    runs-on: ${{ matrix.os }}\n    steps:\n      - run: echo ${NODE_VERSION} | grep ${{ matrix.node }}\n        env:\n          NODE_VERSION: ${{ matrix.node }}\n    strategy:\n      matrix:\n        os: [ubuntu-18.04, macos-latest]\n        node: [4, 6, 8, 10]\n\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node: [8.x, 10.x, 12.x, 13.x]\n    steps:\n      - run: echo ${NODE_VERSION} | grep ${{ matrix.node }}\n        env:\n          NODE_VERSION: ${{ matrix.node }}\n"
  },
  {
    "path": "pkg/runner/testdata/matrix-exitcode/push.yml",
    "content": "name: test\n\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        val: [\"success\", \"failure\"]\n      fail-fast: false\n    steps:\n      - name: test\n        run: |\n          echo \"Expected job result: ${{ matrix.val }}\"\n          [[ \"${{ matrix.val }}\" = \"success\" ]] || exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/matrix-include-exclude/push.yml",
    "content": "name: matrix-include-exclude\non: push\n\njobs:\n  build:\n    name: PHP ${{ matrix.os }} ${{ matrix.node}}\n    runs-on: ${{ matrix.os }}\n    steps:\n      - run: echo ${NODE_VERSION} | grep ${{ matrix.node }}\n        env:\n          NODE_VERSION: ${{ matrix.node }}\n    strategy:\n      matrix:\n        os: [ubuntu-18.04, macos-latest]\n        node: [4, 6, 8, 10]\n        exclude:\n          - os: macos-latest\n            node: 4\n        include:\n          - os: ubuntu-16.04\n            node: 10\n\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node: [8.x, 10.x, 12.x, 13.x]\n    steps:\n      - run: echo ${NODE_VERSION} | grep ${{ matrix.node }}\n        env:\n          NODE_VERSION: ${{ matrix.node }}\n"
  },
  {
    "path": "pkg/runner/testdata/matrix-with-user-inclusions/push.yml",
    "content": "name: matrix-with-user-inclusions\non: push\n\njobs:\n  build:\n    name: PHP ${{ matrix.os }} ${{ matrix.node}}\n    runs-on: ubuntu-latest\n    steps:\n      - run: |\n          echo ${NODE_VERSION} | grep 8\n          echo ${OS_VERSION} | grep ubuntu-18.04\n        env:\n          NODE_VERSION: ${{ matrix.node }}\n          OS_VERSION: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-18.04, macos-latest]\n        node: [4, 6, 8, 10]\n        exclude:\n          - os: macos-latest\n            node: 4\n        include:\n          - os: ubuntu-16.04\n            node: 10\n\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node: [8.x, 10.x, 12.x, 13.x]\n    steps:\n      - run: echo ${NODE_VERSION} | grep 8.x\n        env:\n          NODE_VERSION: ${{ matrix.node }}\n"
  },
  {
    "path": "pkg/runner/testdata/mysql-service-container-with-health-check/push.yml",
    "content": "name: service-container\non: push\njobs:\n  service-container-test:\n    runs-on: ubuntu-latest\n    container: mysql:8\n    services:\n      maindb:\n        image: mysql:8\n        env:\n          MYSQL_DATABASE: dbname\n          MYSQL_USER: dbuser\n          MYSQL_PASSWORD: dbpass\n          MYSQL_RANDOM_ROOT_PASSWORD: yes\n        options: --health-cmd=\"mysqladmin ping\" --health-interval=10s --health-timeout=5s --health-retries=3\n    steps:\n    - run: mysql -u dbuser -D dbname -pdbpass -h maindb -e \"create table T(id INT NOT NULL AUTO_INCREMENT, val VARCHAR(255), PRIMARY KEY (id))\"\n    - run: mysql -u dbuser -D dbname -pdbpass -h maindb -e \"insert into T(val) values ('test'),('h')\"\n    - run: mysql -u dbuser -D dbname -pdbpass -h maindb -e \"select * from T\"\n"
  },
  {
    "path": "pkg/runner/testdata/networking/push.yml",
    "content": "name: test network setup\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Install tools\n        run: |\n          apt update\n          apt install -y iputils-ping\n      - name: Run hostname test\n        run: |\n          hostname -f\n          ping -c 4 $(hostname -f)\n"
  },
  {
    "path": "pkg/runner/testdata/nix-prepend-path/push.yml",
    "content": "on:\r\n  push:\r\ndefaults:\r\n  run:\r\n    shell: sh\r\njobs:\r\n  test:\r\n    runs-on: self-hosted\r\n    steps:\r\n    - run: |\r\n        mkdir build\r\n        echo '#!/usr/bin/env sh' > build/testtool\r\n        echo 'echo Hi' >> build/testtool\r\n        chmod +x build/testtool\r\n    - run: |\r\n        echo '${{ tojson(runner) }}'\r\n        ls\r\n        echo '${{ github.workspace }}'\r\n      working-directory: ${{ github.workspace }}/build\r\n    - run: |\r\n        echo \"$GITHUB_PATH\"\r\n        echo '${{ github.workspace }}/build' > \"$GITHUB_PATH\"\r\n        cat \"$GITHUB_PATH\"\r\n    - run: |\r\n        echo \"$PATH\"\r\n        testtool\r\n"
  },
  {
    "path": "pkg/runner/testdata/no-panic-on-invalid-composite-action/push.yml",
    "content": "on: push\njobs:\n  local-invalid-step:\n    runs-on: ubuntu-latest\n    steps:\n    - run: |\n        runs:\n          using: composite\n          steps:\n          - name: Foo\n          - uses: Foo/Bar\n      shell: cp {0} action.yml\n    - uses: ./\n  local-missing-steps:\n    runs-on: ubuntu-latest\n    steps:\n    - run: |\n        runs:\n          using: composite\n      shell: cp {0} action.yml\n    - uses: ./\n  remote-invalid-step:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: nektos/act-test-actions/invalid-composite-action/invalid-step@main\n  remote-missing-steps:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: nektos/act-test-actions/invalid-composite-action/missing-steps@main"
  },
  {
    "path": "pkg/runner/testdata/node/push.yml",
    "content": "name: NodeJS Test\n\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: actions/setup-node@v1\n        with:\n          node-version: 12.6\n      - run: which node\n      - name: Install Dependencies\n        run: npm install\n"
  },
  {
    "path": "pkg/runner/testdata/non-existent-action/push.yml",
    "content": "on: push\nname: non-existent-action\njobs:\n  nopanic:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: ./path/to/non-existent-action"
  },
  {
    "path": "pkg/runner/testdata/outputs/push.yml",
    "content": "name: output\non: push\n\njobs:\n  build_output:\n    runs-on: ubuntu-latest\n    steps:\n    - id: set_1\n      run: |\n        echo \"::set-output name=var_1::$(echo var1)\"\n        echo \"::set-output name=var_2::$(echo var2)\"\n    - id: set_2\n      run: |\n        echo \"::set-output name=var_3::$(echo var3)\"\n    - id: set_3\n      run: |\n        echo \"::set-output name=var_4::$(echo var4)\"\n    outputs:\n      variable_1: ${{ steps.set_1.outputs.var_1 }}\n      variable_2: ${{ steps.set_1.outputs.var_2 }}\n      variable_3: ${{ steps.set_2.outputs.var_3 }}\n      variable_4: ${{ steps.set_3.outputs.var_4 }}\n\n  build:\n    needs: build_output\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check set_1 var1\n        run: |\n          echo \"${{ needs.build_output.outputs.variable_1 }}\"\n          echo \"${{ needs.build_output.outputs.variable_1 }}\" | grep 'var1' || exit 1\n      - name: Check set_1 var2\n        run: |\n          echo \"${{ needs.build_output.outputs.variable_2 }}\"\n          echo \"${{ needs.build_output.outputs.variable_2 }}\" | grep 'var2' || exit 1\n      - name: Check set_2 var3\n        run: |\n          echo \"${{ needs.build_output.outputs.variable_3 }}\"\n          echo \"${{ needs.build_output.outputs.variable_3 }}\" | grep 'var3' || exit 1\n      - name: Check set_3 var4\n        run: |\n          echo \"${{ needs.build_output.outputs.variable_4 }}\"\n          echo \"${{ needs.build_output.outputs.variable_4 }}\" | grep 'var4' || exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/parallel/push.yml",
    "content": "name: basic\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: ./actions/action1\n        with:\n          args: echo 'build'\n      - uses: actions/hello-world-javascript-action@master\n        with:\n          who-to-greet: 'Mona the Octocat'\n  test1:\n    runs-on: ubuntu-latest\n    needs: [build]\n    steps:\n      - uses: docker://node:16-buster-slim\n        with:\n          args: echo ${GITHUB_REF} | grep nektos/act\n      - uses: ./actions/docker-url\n        with:\n          args: npm install -g qs\n  test2:\n    runs-on: ubuntu-latest\n    needs: [build]\n    steps:\n      - run: echo hello\n      - run: echo world\n"
  },
  {
    "path": "pkg/runner/testdata/path-handling/action/action.yml",
    "content": "name: output action\ndescription: output action\n\ninputs:\n  input:\n    description: some input\n    required: false\n\noutputs:\n  job-output:\n    description: some output\n    value: ${{ steps.gen-out.outputs.step-output }}\n\nruns:\n  using: composite\n  steps:\n    - name: run step\n      id: gen-out\n      run: |\n        echo \"::set-output name=step-output::\"\n      shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/path-handling/push.yml",
    "content": "name: path tests\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n\n      - name: \"Append to $GITHUB_PATH\"\n        run: |\n          echo \"/opt/hostedtoolcache/node/18.99/x64/bin\" >> $GITHUB_PATH\n \n      - name: test path (after setup)\n        run: |\n          if ! echo \"$PATH\" |grep \"/opt/hostedtoolcache/node/18.*/\\(x64\\|arm64\\)/bin\" ; then\n            echo \"Node binaries not in path: $PATH\"\n            exit 1\n          fi\n\n      - id: action-with-output\n        uses: ./path-handling/action/\n\n      - name: test path (after local action)\n        run: |\n          if ! echo \"$PATH\" |grep \"/opt/hostedtoolcache/node/18.*/\\(x64\\|arm64\\)/bin\" ; then\n            echo \"Node binaries not in path: $PATH\"\n            exit 1\n          fi\n\n      - uses: nektos/act-test-actions/composite@main\n        with:\n          input: some input\n\n      - name: test path (after remote action)\n        run: |\n          if ! echo \"$PATH\" |grep \"/opt/hostedtoolcache/node/18.*/\\(x64\\|arm64\\)/bin\" ; then\n            echo \"Node binaries not in path: $PATH\"\n            exit 1\n          fi\n"
  },
  {
    "path": "pkg/runner/testdata/post-step-failure-is-job-failure/post-step-failure/action.yml",
    "content": "runs:\n  using: node20\n  main: main.js\n  post: post.js "
  },
  {
    "path": "pkg/runner/testdata/post-step-failure-is-job-failure/post-step-failure/main.js",
    "content": ""
  },
  {
    "path": "pkg/runner/testdata/post-step-failure-is-job-failure/post-step-failure/post.js",
    "content": "console.log('This is a post step failure test');\nprocess.exit(1);"
  },
  {
    "path": "pkg/runner/testdata/post-step-failure-is-job-failure/push.yml",
    "content": "name: basic\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ./post-step-failure-is-job-failure/post-step-failure"
  },
  {
    "path": "pkg/runner/testdata/pull-request/event.json",
    "content": "{\n  \"pull_request\": {\n    \"head\": {\n      \"ref\": \"sample-head-ref\"\n    },\n    \"base\": {\n      \"ref\": \"sample-base-ref\"\n    }\n  }\n}\n"
  },
  {
    "path": "pkg/runner/testdata/pull-request/main.yaml",
    "content": "name: basic\non: pull_request\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      # test refs from event.json\n      - run: echo '${{github.ref}}'\n      - run: echo '${{github.head_ref}}' | grep sample-head-ref\n      - run: echo '${{github.base_ref}}' | grep sample-base-ref\n      # test main/composite context equality with data from event.json\n      - run: |\n          runs:\n            using: composite\n            steps:\n            - run: |\n                echo WORKFLOW_GITHUB_CONTEXT=\"$WORKFLOW_GITHUB_CONTEXT\"\n                echo COMPOSITE_GITHUB_CONTEXT=\"$COMPOSITE_GITHUB_CONTEXT\"\n                [[ \"$WORKFLOW_GITHUB_CONTEXT\" = \"$COMPOSITE_GITHUB_CONTEXT\" ]]\n              env:\n                WORKFLOW_GITHUB_CONTEXT: ${{ tojson(tojson(github.event)) }}\n                COMPOSITE_GITHUB_CONTEXT: ${{ '${{tojson(github.event)}}' }}\n              shell: bash\n        shell: cp {0} action.yml\n      - uses: ./\n"
  },
  {
    "path": "pkg/runner/testdata/python/main.yml",
    "content": "name: CI\n\non: [push]\n\njobs:\n  linter:\n    name: \"Linting Python Code\"\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v2\n    - uses: actions/setup-python@v1.1.1\n      with:\n        python-version: 3.7\n\n    - run: python -c \"import sys; print(sys.version)\"\n"
  },
  {
    "path": "pkg/runner/testdata/remote-action-composite-action-ref/push.yml",
    "content": "name: remote-action-composite-action-ref\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: nektos/act-test-actions/composite-assert-action-ref-action@main\n"
  },
  {
    "path": "pkg/runner/testdata/remote-action-composite-js-pre-with-defaults/push.yml",
    "content": "name: remote-action-composite-js-pre-with-defaults\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: nektos/act-test-actions/composite-js-pre-with-defaults/js@main\n      with:\n        in: nix\n    - uses: nektos/act-test-actions/composite-js-pre-with-defaults@main\n      with:\n        in: secretval\n    - uses: nektos/act-test-actions/composite-js-pre-with-defaults@main\n      with:\n        in: secretval\n    - uses: nektos/act-test-actions/composite-js-pre-with-defaults/js@main\n      with:\n        pre: \"true\"\n        in: nix\n    - uses: nektos/act-test-actions/composite-js-pre-with-defaults/js@main\n      with:\n        in: nix"
  },
  {
    "path": "pkg/runner/testdata/remote-action-docker/push.yml",
    "content": "name: remote-action-docker\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/hello-world-docker-action@v1\n      with:\n        who-to-greet: 'Mona the Octocat'\n"
  },
  {
    "path": "pkg/runner/testdata/remote-action-docker-new-cache/config/config.yml",
    "content": "local-repositories: {}\n"
  },
  {
    "path": "pkg/runner/testdata/remote-action-docker-new-cache/push.yml",
    "content": "name: remote-action-docker\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/hello-world-docker-action@v1\n      with:\n        who-to-greet: 'Mona the Octocat'\n"
  },
  {
    "path": "pkg/runner/testdata/remote-action-js/push.yml",
    "content": "name: remote-action-js\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/hello-world-javascript-action@v1\n      with:\n        who-to-greet: 'Mona the Octocat'\n\n    - uses: cloudposse/actions/github/slash-command-dispatch@0.14.0\n"
  },
  {
    "path": "pkg/runner/testdata/remote-action-js-node-user/push.yml",
    "content": "name: remote-action-js\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    container:\n      image: node:16-buster-slim\n      options: --user node\n    steps:\n    - name: check permissions of env files\n      id: test\n      run: |\n        echo \"USER: $(id -un) expected: node\"\n        [[ \"$(id -un)\" = \"node\" ]]\n        echo \"TEST=Value\" >> $GITHUB_OUTPUT\n      shell: bash\n\n    - name: check if file command worked\n      if: steps.test.outputs.test != 'Value'\n      run: |\n        echo \"steps.test.outputs.test=${{ steps.test.outputs.test || 'missing value!' }}\"\n        exit 1\n      shell: bash\n\n    - uses: actions/hello-world-javascript-action@v1\n      with:\n        who-to-greet: 'Mona the Octocat'\n\n    - uses: cloudposse/actions/github/slash-command-dispatch@0.14.0\n"
  },
  {
    "path": "pkg/runner/testdata/runs-on/push.yml",
    "content": "name: runs-on\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - run: env\n    - run: echo ${GITHUB_ACTOR} \n    - run: echo ${GITHUB_ACTOR} | grep nektos/act\n\n  many:\n    runs-on: [ubuntu-latest]\n    steps:\n      - run: env\n      - run: echo ${GITHUB_ACTOR}\n      - run: echo ${GITHUB_ACTOR} | grep nektos/act\n\n  selfmany:\n    runs-on: [self-hosted, ubuntu-latest]\n    steps:\n      - run: env\n      - run: echo ${GITHUB_ACTOR}\n      - run: echo ${GITHUB_ACTOR} | grep nektos/act\n"
  },
  {
    "path": "pkg/runner/testdata/secrets/.actrc",
    "content": "-W .\n--secret-file .secrets\n"
  },
  {
    "path": "pkg/runner/testdata/secrets/push.yml",
    "content": "name: basic\non: push\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - run: |\n          echo '${{secrets.MY_SECRET}}' | grep 'top-secret'\n      - run: |\n          echo \"${{secrets.MULTILINE_SECRET}}\" | wc -l | grep 3\n      - run: |\n          echo '${{secrets.JSON_SECRET}}' | grep \"{\\\"foo\\\": \\\"bar\\\"}\"\n      - run: |\n          echo '${{env.HELLO}}' | grep \"WORLD\"\n      - run: |\n          echo \"${{env.MULTILINE_ENV}}\" | wc -l | grep 3\n"
  },
  {
    "path": "pkg/runner/testdata/services/push.yaml",
    "content": "name: services\non: push\njobs:\n  services:\n    name: Reproduction of failing Services interpolation\n    runs-on: ubuntu-latest\n    services:\n      postgres:\n        image: postgres:12\n        env:\n          POSTGRES_USER: runner\n          POSTGRES_PASSWORD: mysecretdbpass\n          POSTGRES_DB: mydb\n        options: >-\n          --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n        ports:\n          - 5432:5432\n    steps:\n      - name: Echo the Postgres service ID / Network / Ports\n        run: |\n          echo \"id: ${{ job.services.postgres.id }}\"\n          echo \"network: ${{ job.services.postgres.network }}\"\n          echo \"ports: ${{ job.services.postgres.ports }}\"\n"
  },
  {
    "path": "pkg/runner/testdata/services-empty-image/push.yaml",
    "content": "name: services\non: push\njobs:\n  services:\n    name: Reproduction of failing Services interpolation\n    runs-on: ubuntu-latest\n    services:\n      postgres:\n        image: ${{ false || '' }}\n        env:\n          POSTGRES_USER: runner\n          POSTGRES_PASSWORD: mysecretdbpass\n          POSTGRES_DB: mydb\n        options: >-\n          --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n        ports:\n          - 5432:5432\n    steps:\n      - name: Echo the Postgres service ID / Network / Ports\n        run: |\n          echo \"id: ${{ job.services.postgres.id }}\"\n          echo \"network: ${{ job.services.postgres.network }}\"\n          echo \"ports: ${{ job.services.postgres.ports }}\"\n"
  },
  {
    "path": "pkg/runner/testdata/services-host-network/push.yml",
    "content": "name: services-host-network\non: push\njobs:\n  services-host-network:\n    runs-on: ubuntu-latest\n    services:\n      nginx:\n        image: \"nginx:latest\"\n        ports:\n          - \"8080:80\"\n    steps:\n      - run: apt-get -qq update && apt-get -yqq install --no-install-recommends curl net-tools\n      - run: netstat -tlpen\n      - run: curl -v http://localhost:8080\n"
  },
  {
    "path": "pkg/runner/testdata/services-with-container/push.yml",
    "content": "name: services-with-containers\non: push\njobs:\n  services-with-containers:\n    runs-on: ubuntu-latest\n    # https://docs.github.com/en/actions/using-containerized-services/about-service-containers#running-jobs-in-a-container\n    container:\n      image: \"ubuntu:latest\"\n    services:\n      nginx:\n        image: \"nginx:latest\"\n        ports:\n          - \"8080:80\"\n    steps:\n      - run: apt-get -qq update && apt-get -yqq install --no-install-recommends curl\n      - run: curl -v http://nginx:80\n"
  },
  {
    "path": "pkg/runner/testdata/set-env-new-env-file-per-step/push.yml",
    "content": "on: push\njobs:\n  _:\n    runs-on: ubuntu-latest\n    env:\n      MY_ENV: test\n    steps:\n    - run: exit 1\n      if: env.MY_ENV != 'test'\n    - run: echo \"MY_ENV=test2\" > $GITHUB_ENV\n    - run: exit 1\n      if: env.MY_ENV != 'test2'\n    - run: echo \"MY_ENV=returnedenv\" > $GITHUB_ENV\n    - run: exit 1\n      if: env.MY_ENV != 'returnedenv'"
  },
  {
    "path": "pkg/runner/testdata/set-env-step-env-override/push.yml",
    "content": "on: push\njobs:\n  _:\n    runs-on: ubuntu-latest\n    env:\n      MY_ENV: test\n    steps:\n    - run: exit 1\n      if: env.MY_ENV != 'test'\n    - run: |\n        runs:\n          using: composite\n          steps:\n          - run: exit 1\n            shell: bash\n            if: env.MY_ENV != 'val'\n          - run: echo \"MY_ENV=returnedenv\" > $GITHUB_ENV\n            shell: bash\n      shell: cp {0} action.yml\n    - uses: ./\n      env:\n        MY_ENV: val\n    - run: exit 1\n      if: env.MY_ENV != 'returnedenv'"
  },
  {
    "path": "pkg/runner/testdata/shells/bash/push.yml",
    "content": "on: push\nenv:\n  MY_SHELL: bash\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - shell: bash\n        run: |\n          if [[ -n \"$BASH\" ]]; then\n            echo \"I'm $BASH!\"\n          else\n            exit 1\n          fi\n  check-container:\n    runs-on: ubuntu-latest\n    container: node:16-buster-slim\n    steps:\n      - shell: bash\n        run: |\n          if [[ -n \"$BASH\" ]]; then\n            echo \"I'm $BASH!\"\n          else\n            exit 1\n          fi\n  check-job-default:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        shell: ${{ env.MY_SHELL }}\n    steps:\n      - run: |\n          if [[ -n \"$BASH\" ]]; then\n            echo \"I'm $BASH!\"\n          else\n            exit 1\n          fi\n"
  },
  {
    "path": "pkg/runner/testdata/shells/custom/push.yml",
    "content": "on: push\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      # prints version and exits, it's not valid (for github) if {0} is not included\n      - shell: pwsh -v '. {0}'\n        run: ''\n  check-container:\n    runs-on: ubuntu-latest\n    container: catthehacker/ubuntu:pwsh-latest\n    steps:\n      - shell: pwsh -v '. {0}'\n        run: ''\n"
  },
  {
    "path": "pkg/runner/testdata/shells/defaults/push.yml",
    "content": "on: push\njobs:\n  check: # GHA uses `bash` as default for runners\n    runs-on: ubuntu-latest\n    steps:\n      - run: |\n          if [[ -n \"$BASH\" ]]; then\n            echo \"I'm $BASH!\"\n          else\n            exit 1\n          fi\n  check-container: # GHA uses `sh` as default for containers\n    runs-on: ubuntu-latest\n    container: alpine:latest\n    steps:\n      - run: |\n          if [ -z ${BASH+x} ]; then\n            echo \"I'm sh!\"\n          else\n            exit 1\n          fi\n"
  },
  {
    "path": "pkg/runner/testdata/shells/pwsh/push.yml",
    "content": "on: push\nenv:\n  MY_SHELL: pwsh\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - shell: pwsh\n        run: |\n          $PSVersionTable\n  check-container:\n    runs-on: ubuntu-latest\n    container: catthehacker/ubuntu:pwsh-latest\n    steps:\n      - shell: pwsh\n        run: |\n          $PSVersionTable\n  check-job-default:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        shell: ${{ env.MY_SHELL }}\n    steps:\n      - run: |\n          $PSVersionTable\n"
  },
  {
    "path": "pkg/runner/testdata/shells/python/push.yml",
    "content": "on: push\nenv:\n  MY_SHELL: python\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - shell: python\n        run: |\n          import platform\n          print(platform.python_version())\n  check-container:\n    runs-on: ubuntu-latest\n    container: node:16-buster\n    steps:\n      - shell: python\n        run: |\n          import platform\n          print(platform.python_version())\n  check-job-default:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        shell: ${{ env.MY_SHELL }}\n    steps:\n      - run: |\n          import platform\n          print(platform.python_version())\n"
  },
  {
    "path": "pkg/runner/testdata/shells/sh/push.yml",
    "content": "on: push\nenv:\n  MY_SHELL: sh\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - shell: sh\n        run: |\n          if [ -z ${BASH+x} ]; then\n            echo \"I'm sh!\"\n          else\n            exit 1\n          fi\n  check-container:\n    runs-on: ubuntu-latest\n    container: alpine:latest\n    steps:\n      - shell: sh\n        run: |\n          if [ -z ${BASH+x} ]; then\n            echo \"I'm sh!\"\n          else\n            exit 1\n          fi\n  check-job-default:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        shell: ${{ env.MY_SHELL }}\n    steps:\n      - run: |\n          if [ -z ${BASH+x} ]; then\n            echo \"I'm sh!\"\n          else\n            exit 1\n          fi\n"
  },
  {
    "path": "pkg/runner/testdata/steps-context/conclusion/push.yml",
    "content": "name: conclusion\non: push\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - id: first\n        run: exit 0\n      - id: second\n        continue-on-error: true\n        run: exit 1\n      - run: echo '${{ steps.first.conclusion }}' | grep 'success'\n      - run: echo '${{ steps.second.conclusion }}' | grep 'success'\n"
  },
  {
    "path": "pkg/runner/testdata/steps-context/outcome/push.yml",
    "content": "name: outcome\non: push\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - id: first\n        run: exit 0\n      - id: second\n        continue-on-error: true\n        run: exit 1\n      - run: echo '${{ steps.first.outcome }}' | grep 'success'\n      - run: echo '${{ steps.second.outcome }}' | grep 'failure'\n"
  },
  {
    "path": "pkg/runner/testdata/stepsummary/push.yml",
    "content": "name: Step Summary Example\n\non: [push]\n\njobs:\n  create_summary:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      # GITHUB_STEP_SUMMARY test\n      - name: Create Step Summary\n        uses: actions/github-script@v7\n        with:\n          script: |\n            const summary = `\n            ## Workflow Summary\n            - **Repository**: ${context.repo.owner}/${context.repo.repo}\n            - **Branch**: ${context.ref}\n            - **Commit SHA**: ${context.sha}\n            - **Event**: ${context.eventName}\n            `;\n            console.log('Summary:', summary);\n            await core.summary.addRaw(summary);\n            await core.summary.write();\n          github-token: none\n"
  },
  {
    "path": "pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/action.yml",
    "content": "name: \"last action check\"\ndescription: \"last action check\"\n\nruns:\n  using: \"node16\"\n  main: main.js\n  post: post.js\n"
  },
  {
    "path": "pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/main.js",
    "content": ""
  },
  {
    "path": "pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/post.js",
    "content": "const pre = process.env['ACTION_OUTPUT_PRE'];\nconst main = process.env['ACTION_OUTPUT_MAIN'];\nconst post = process.env['ACTION_OUTPUT_POST'];\n\nconsole.log({pre, main, post});\n\nif (pre !== 'pre') {\n  throw new Error(`Expected 'pre' but got '${pre}'`);\n}\n\nif (main !== 'main') {\n  throw new Error(`Expected 'main' but got '${main}'`);\n}\n\nif (post !== 'post') {\n  throw new Error(`Expected 'post' but got '${post}'`);\n}\n"
  },
  {
    "path": "pkg/runner/testdata/uses-action-with-pre-and-post-step/push.yml",
    "content": "name: uses-action-with-pre-and-post-step\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: ./uses-action-with-pre-and-post-step/last-action\n      - uses: nektos/act-test-actions/js-with-pre-and-post-step@main\n        with:\n          pre: true\n          post: true\n      - run: |\n          cat $GITHUB_ENV\n"
  },
  {
    "path": "pkg/runner/testdata/uses-and-run-in-one-step/push.yml",
    "content": "name: uses-and-run-in-one-step\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Test\n        run: echo\n        uses: actions/checkout@v2\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite/composite_action/action.yml",
    "content": "---\nname: \"Test Composite Action\"\ndescription: \"Test action uses composite\"\n\ninputs:\n  test_input_required:\n    description: \"Required input\"\n    required: true\n  test_input_optional:\n    description: \"optional defaulted input\"\n    required: false\n    default: \"test_input_optional_value\"\n  test_input_optional_with_default_overriden:\n    description: \"optional defaulted input\"\n    required: false\n    default: \"test_input_optional_value\"\n  test_input_required_with_default:\n    description: \"Required with default, due to an old bug of github actions this is allowed\"\n    required: true\n    default: \"test_input_optional_value\"\n  test_input_required_with_default_overriden:\n    description: \"Required with default, due to an old bug of github actions this is allowed\"\n    required: true\n    default: \"test_input_optional_value\"\n  secret_input:\n    description: test pass a secret as input\noutputs:\n  test_output:\n    description: \"Output value to pass up\"\n    value: ${{ steps.output.outputs.test_output }}\n  secret_output:\n    description: test pass a secret as output\n    value: ${{ format('{0}/{1}', inputs.secret_input, env.secret_input) }}\n\nruns:\n  using: \"composite\"\n  steps:\n    - name: echo inputs\n      run: |\n        echo \"#####################################\"\n        echo \"Inputs:\"\n        echo \"---\"\n        echo \"test_input_required=${{ inputs.test_input_required }}\"\n        echo \"test_input_optional=${{ inputs.test_input_optional }}\"\n        echo \"test_input_optional_with_default_overriden=${{ inputs.test_input_optional_with_default_overriden }}\"\n        echo \"test_input_required_with_default=${{ inputs.test_input_required_with_default }}\"\n        echo \"test_input_required_with_default_overriden=${{ inputs.test_input_required_with_default_overriden }}\"\n        echo \"---\"\n      shell: bash\n\n    # Let's test the inputs\n    - run: |\n        if [ \"${{ inputs.test_input_required }}\" != \"test_input_required_value\" ]; then\n          exit 1\n        fi\n      shell: bash\n\n    - run: |\n        if [ \"${{ inputs.test_input_optional }}\" != \"test_input_optional_value\" ]; then\n          exit 1\n        fi\n      shell: bash\n\n    - run: |\n        if [ \"${{ inputs.test_input_optional_with_default_overriden }}\" != \"test_input_optional_with_default_overriden\" ]; then\n          exit 1\n        fi\n      shell: bash\n\n    - run: |\n        if [ \"${{ inputs.test_input_required_with_default }}\" != \"test_input_optional_value\" ]; then\n          exit 1\n        fi\n      shell: bash\n\n    - run: |\n        if [ \"${{ inputs.test_input_required_with_default_overriden }}\" != \"test_input_required_with_default_overriden\" ]; then\n          exit 1\n        fi\n      shell: bash\n\n    - run: |\n        if [ -z \"$GITHUB_ACTION_PATH\" ]; then\n          exit 1\n        fi\n        if [ -z \"${{ github.action_path }}\" ]; then\n          exit 2\n        fi\n      shell: bash\n\n    # Let's send up an output to test\n    - run: echo \"::set-output name=test_output::test_output_value\"\n      id: output\n      shell: bash\n    - run: echo \"COMPOSITE_ACTION_ENV_OUTPUT=my test value\" >> $GITHUB_ENV\n      shell: bash\n\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite/push.yml",
    "content": "name: uses-docker-url\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./uses-composite/composite_action\n      id: composite\n      with:\n        test_input_required: 'test_input_required_value'\n        test_input_optional: 'test_input_optional_value'\n        test_input_optional_with_default_overriden: 'test_input_optional_with_default_overriden'\n        test_input_required_with_default: 'test_input_optional_value'\n        test_input_required_with_default_overriden: 'test_input_required_with_default_overriden'\n        secret_input: ${{secrets.test_input_optional || 'NO SUCH SECRET'}}\n      env:\n        secret_input: ${{secrets.test_input_optional || 'NO SUCH SECRET'}}\n    - if: steps.composite.outputs.test_output != 'test_output_value'\n      run: |\n        echo \"steps.composite.outputs.test_output=${{ steps.composite.outputs.test_output }}\"\n        exit 1\n    - run: |\n        echo \"steps.composite.outputs.secret_output=${{ steps.composite.outputs.secret_output }}\"\n        [[ \"${{steps.composite.outputs.secret_output == format('{0}/{0}', secrets.test_input_optional || 'NO SUCH SECRET')}}\" = \"true\" ]] || exit 1\n      shell: bash\n    - run: |\n        echo \"steps.composite.outputs.secret_output=$COMPOSITE_ACTION_ENV_OUTPUT\"\n        [[ \"${{env.COMPOSITE_ACTION_ENV_OUTPUT == 'my test value' }}\" = \"true\" ]] || exit 1\n      shell: bash\n\n    # Now test again with default values\n    - uses: ./uses-composite/composite_action\n      id: composite2\n      with:\n        test_input_required: 'test_input_required_value'\n        test_input_optional_with_default_overriden: 'test_input_optional_with_default_overriden'\n        test_input_required_with_default_overriden: 'test_input_required_with_default_overriden'\n\n    - if: steps.composite2.outputs.test_output != 'test_output_value'\n      run: |\n        echo \"steps.composite.outputs.test_output=${{ steps.composite2.outputs.test_output }}\"\n        exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-collision/action-with-pre-and-post/action.yml",
    "content": "name: \"Action with pre and post\"\ndescription: \"Action with pre and post\"\n\ninputs:\n  step:\n    description: \"step\"\n    required: true\n  cache:\n    required: false\n    default: false\n\nruns:\n  using: \"node16\"\n  pre: pre.js\n  main: main.js\n  post: post.js\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-collision/action-with-pre-and-post/main.js",
    "content": "const { appendFileSync } = require('fs');\nconst step = process.env['INPUT_STEP'];\nappendFileSync(process.env['GITHUB_ENV'], `TEST=${step}`, { encoding:'utf-8' })\n\nvar cache = process.env['INPUT_CACHE']\ntry {\n    var cache = JSON.parse(cache)\n} catch {\n\n}\nif(typeof cache !== 'boolean') {\n    console.log(\"Input Polluted boolean true/false expected, got \" + cache)\n    process.exit(1);\n}"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-collision/action-with-pre-and-post/post.js",
    "content": "const { appendFileSync } = require('fs');\nconst step = process.env['INPUT_STEP'];\nappendFileSync(process.env['GITHUB_ENV'], `TEST=${step}-post`, { encoding:'utf-8' })\n\nvar cache = process.env['INPUT_CACHE']\ntry {\n    var cache = JSON.parse(cache)\n} catch {\n\n}\nif(typeof cache !== 'boolean') {\n    console.log(\"Input Polluted boolean true/false expected, got \" + cache)\n    process.exit(1);\n}"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-collision/action-with-pre-and-post/pre.js",
    "content": "console.log('pre');\n\nvar cache = process.env['INPUT_CACHE']\ntry {\n    var cache = JSON.parse(cache)\n} catch {\n\n}\nif(typeof cache !== 'boolean') {\n    console.log(\"Input Polluted boolean true/false expected, got \" + cache)\n    process.exit(1);\n}"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-collision/composite_action/action.yml",
    "content": "name: \"Test Composite Action\"\ndescription: \"Test action uses composite\"\n\ninputs:\n  cache:\n    default: none\n\nruns:\n  using: \"composite\"\n  steps:\n  - uses: ./uses-composite-check-for-input-collision/action-with-pre-and-post\n    with:\n      step: step1\n  - uses: ./uses-composite-check-for-input-collision/action-with-pre-and-post\n    with:\n      step: step2\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-collision/push.yml",
    "content": "name: uses-composite-with-pre-and-post-steps\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - run: echo -n \"STEP_OUTPUT_TEST=empty\" >> $GITHUB_ENV\n      - uses: ./uses-composite-check-for-input-collision/composite_action\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-in-if-uses/composite_action/action.yml",
    "content": "name: \"Test Composite Action\"\ndescription: \"Test action uses composite\"\n\ninputs:\n  b:\n    default: true\n  b2: {}\n\nruns:\n  using: \"composite\"\n  steps:\n  - uses: actions/github-script@v7\n    if: inputs.b == 'true'\n    with:\n      script: |\n        console.log(${{ tojson(inputs) }})\n        if( ${{ tojson(inputs.b) }} != 'true' ) {\n          process.exit(-1);\n        }\n      github-token: noop\n  - uses: actions/github-script@v7\n    if: inputs.b != 'true'\n    with:\n      script: |\n        console.log(${{ tojson(inputs) }})\n        if( ${{ tojson(inputs.b) }} == 'true' ) {\n          process.exit(-1);\n        }\n      github-token: noop\n  - uses: actions/github-script@v7\n    if: inputs.b2 == 'false'\n    with:\n      script: |\n        console.log(${{ tojson(inputs) }})\n        if( ${{ tojson(inputs.b2) }} != 'false' ) {\n          process.exit(-1);\n        }\n      github-token: noop\n  - uses: actions/github-script@v7\n    if: inputs.b2 != 'false'\n    with:\n      script: |\n        console.log(${{ tojson(inputs) }})\n        if( ${{ tojson(inputs.b2) }} == 'false' ) {\n          process.exit(-1);\n        }\n      github-token: noop\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-in-if-uses/push.yml",
    "content": "name: uses-composite-check-for-input-in-if-uses\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ./uses-composite-check-for-input-in-if-uses/composite_action\n        with:\n          b: true\n          b2: true\n      - uses: ./uses-composite-check-for-input-in-if-uses/composite_action\n        with:\n          b: false\n          b2: false\n      - uses: ./uses-composite-check-for-input-in-if-uses/composite_action\n        with:\n          b: true\n          b2: false\n      - uses: ./uses-composite-check-for-input-in-if-uses/composite_action\n        with:\n          b: false\n          b2: true"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-shadowing/action-with-pre-and-post/action.yml",
    "content": "name: \"Action with pre and post\"\ndescription: \"Action with pre and post\"\n\ninputs:\n  step:\n    description: \"step\"\n    required: true\n  cache:\n    required: false\n    default: false\n\nruns:\n  using: \"node16\"\n  pre: pre.js\n  main: main.js\n  post: post.js\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-shadowing/action-with-pre-and-post/main.js",
    "content": "const { appendFileSync } = require('fs');\nconst step = process.env['INPUT_STEP'];\nappendFileSync(process.env['GITHUB_ENV'], `TEST=${step}`, { encoding:'utf-8' })\n\nvar cache = process.env['INPUT_CACHE']\ntry {\n    var cache = JSON.parse(cache)\n} catch {\n\n}\nif(typeof cache !== 'boolean') {\n    console.log(\"Input Polluted boolean true/false expected, got \" + cache)\n    process.exit(1);\n}"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-shadowing/action-with-pre-and-post/post.js",
    "content": "const { appendFileSync } = require('fs');\nconst step = process.env['INPUT_STEP'];\nappendFileSync(process.env['GITHUB_ENV'], `TEST=${step}-post`, { encoding:'utf-8' })\n\nvar cache = process.env['INPUT_CACHE']\ntry {\n    var cache = JSON.parse(cache)\n} catch {\n\n}\nif(typeof cache !== 'boolean') {\n    console.log(\"Input Polluted boolean true/false expected, got \" + cache)\n    process.exit(1);\n}"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-shadowing/action-with-pre-and-post/pre.js",
    "content": "console.log('pre');\n\nvar cache = process.env['INPUT_CACHE']\ntry {\n    var cache = JSON.parse(cache)\n} catch {\n\n}\nif(typeof cache !== 'boolean') {\n    console.log(\"Input Polluted boolean true/false expected, got \" + cache)\n    process.exit(1);\n}"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-shadowing/composite_action/action.yml",
    "content": "name: \"Test Composite Action\"\ndescription: \"Test action uses composite\"\n\ninputs:\n  cache:\n    default: true\n\nruns:\n  using: \"composite\"\n  steps:\n  - uses: ./uses-composite-check-for-input-shadowing/action-with-pre-and-post\n    with:\n      step: step1\n      cache: ${{ inputs.cache || 'none' }}\n  - uses: ./uses-composite-check-for-input-shadowing/action-with-pre-and-post\n    with:\n      step: step2\n      cache: ${{ inputs.cache || 'none' }}\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-check-for-input-shadowing/push.yml",
    "content": "name: uses-composite-with-pre-and-post-steps\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - run: echo -n \"STEP_OUTPUT_TEST=empty\" >> $GITHUB_ENV\n      - uses: ./uses-composite-check-for-input-shadowing/composite_action\n        # with:\n          # cache: other\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-error/composite_action2/action.yml",
    "content": "---\nname: \"Test Composite Action\"\ndescription: \"Test action uses composite\"\n\nruns:\n  using: \"composite\"\n  steps:\n  - run: exit 1\n    shell: bash\n  - run: echo should not run in composite steps\n    shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-error/push.yml",
    "content": "name: uses-docker-url\non: push\n\njobs:\n  failing-composite-action:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./uses-composite-with-error/composite_action2\n    - run: echo should run\n      if: failure()\n    - run: echo should not run\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-inputs/action/action.yml",
    "content": "name: \"action\"\ndescription: \"action\"\n\ninputs:\n  some:\n    description: \"some input\"\n    required: true\n  other:\n    description: \"other input\"\n    default: \"${{ inputs.some }}\"\n    required: false\noutputs:\n  out:\n    description: \"some output\"\n    value: \"output value\"\n\nruns:\n  using: \"composite\"\n  steps:\n    - run: |\n        echo \"action input=${{ inputs.some }}\"\n        [[ \"${{ inputs.some == 'value' }}\" = \"true\" ]] || exit 1\n      shell: bash\n    - run: |\n        echo \"ENV_VAR=$ENV_VAR\"\n        [[ \"$ENV_VAR\" = \"value\" ]] || exit 1\n      shell: bash\n      env:\n        ENV_VAR: ${{ inputs.other }}\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-inputs/composite/action.yml",
    "content": "name: \"composite\"\ndescription: \"composite\"\n\ninputs:\n  composite-input:\n    description: \"value\"\n    required: true\n\nruns:\n  using: \"composite\"\n  steps:\n    - name: test input value\n      run: |\n        echo \"input value 1=${{ inputs.composite-input }}\"\n        [[ \"${{ inputs.composite-input == 'value' }}\" = \"true\" ]] || exit 1\n      shell: bash\n    - uses: nektos/act-test-actions/js@main\n    - name: test input value again\n      run: |\n        echo \"input value 2=${{ inputs.composite-input }}\"\n        [[ \"${{ inputs.composite-input == 'value' }}\" = \"true\" ]] || exit 1\n      shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-inputs/push.yml",
    "content": "name: push\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - id: set-output\n      run: echo \"::set-output name=var::value\"\n    - name: use simple composite action\n      uses: ./uses-composite-with-inputs/action\n      with:\n        some: ${{ steps.set-output.outputs.var }}\n    - name: use nested composite action\n      uses: ./uses-composite-with-inputs/composite\n      with:\n        composite-input: value\n    ###\n    #\n    # Remote composite test\n    #\n    - name: use remote composite action\n      id: remote-composite\n      uses: nektos/act-test-actions/composite@main\n      with:\n        input: ${{ steps.set-output.outputs.var }}\n    - name: test remote composite output\n      run: |\n        echo \"steps.remote-composite.outputs.output=${{ steps.remote-composite.outputs.output }}\"\n        [[ \"${{ steps.remote-composite.outputs.output == 'value' }}\" = \"true\" ]] || exit 1\n    #\n    ###\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/action-with-pre-and-post/action.yml",
    "content": "name: \"Action with pre and post\"\ndescription: \"Action with pre and post\"\n\ninputs:\n  step:\n    description: \"step\"\n    required: true\n\nruns:\n  using: \"node16\"\n  pre: pre.js\n  main: main.js\n  post: post.js\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/action-with-pre-and-post/main.js",
    "content": "const { appendFileSync } = require('fs');\nconst step = process.env['INPUT_STEP'];\nappendFileSync(process.env['GITHUB_ENV'], `;${step}`, { encoding:'utf-8' })\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/action-with-pre-and-post/post.js",
    "content": "const { appendFileSync } = require('fs');\nconst step = process.env['INPUT_STEP'];\nappendFileSync(process.env['GITHUB_ENV'], `;${step}-post`, { encoding:'utf-8' })\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/action-with-pre-and-post/pre.js",
    "content": "console.log('pre');\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/composite_action/action.yml",
    "content": "name: \"Test Composite Action\"\ndescription: \"Test action uses composite\"\n\nruns:\n  using: \"composite\"\n  steps:\n  - uses: ./uses-composite-with-pre-and-post-steps/action-with-pre-and-post\n    with:\n      step: step1\n  - uses: ./uses-composite-with-pre-and-post-steps/action-with-pre-and-post\n    with:\n      step: step2\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/last-action/action.yml",
    "content": "name: \"last action check\"\ndescription: \"last action check\"\n\nruns:\n  using: \"node16\"\n  main: main.js\n  post: post.js\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/last-action/main.js",
    "content": ""
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/last-action/post.js",
    "content": "const output = process.env['STEP_OUTPUT_TEST'];\nconst expected = 'empty;step1;step2;step2-post;step1-post';\n\nconsole.log(output);\nif (output !== expected) {\n  throw new Error(`Expected '${expected}' but got '${output}'`);\n}\n"
  },
  {
    "path": "pkg/runner/testdata/uses-composite-with-pre-and-post-steps/push.yml",
    "content": "name: uses-composite-with-pre-and-post-steps\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: ./uses-composite-with-pre-and-post-steps/last-action\n      - uses: actions/checkout@v2\n      - run: echo -n \"STEP_OUTPUT_TEST=empty\" >> $GITHUB_ENV\n      - uses: ./uses-composite-with-pre-and-post-steps/composite_action\n"
  },
  {
    "path": "pkg/runner/testdata/uses-docker-url/push.yml",
    "content": "name: uses-docker-url\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: docker://node:16-buster-slim\n        with:\n          somekey: somevalue\n          args: echo ${INPUT_SOMEKEY} | grep somevalue\n      - uses: docker://node:16-buster-slim\n        with:\n          args: -v\n      - uses: docker://node:16-buster-slim\n        with:\n          entrypoint: /bin/sh\n          args: -c -- uname -a\n      - uses: docker://node:16-buster-slim\n        with:\n          entrypoint: /bin/sh\n          args: -c 'uname -a'\n\n"
  },
  {
    "path": "pkg/runner/testdata/uses-github-empty/push.yml",
    "content": "name: uses-github-empty\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - name: empty\n"
  },
  {
    "path": "pkg/runner/testdata/uses-github-full-sha/main.yml",
    "content": "name: uses-github-root\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/hello-world-docker-action@b136eb8894c5cb1dd5807da824be97ccdf9b5423\n"
  },
  {
    "path": "pkg/runner/testdata/uses-github-noref/push.yml",
    "content": "name: uses-github-noref\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout\n"
  },
  {
    "path": "pkg/runner/testdata/uses-github-path/push.yml",
    "content": "name: uses-github-path\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: sergioramos/yarn-actions/install@v6\n"
  },
  {
    "path": "pkg/runner/testdata/uses-github-root/push.yml",
    "content": "name: uses-github-root\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n"
  },
  {
    "path": "pkg/runner/testdata/uses-github-short-sha/main.yml",
    "content": "name: uses-github-root\non: push\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/hello-world-docker-action@b136eb8\n"
  },
  {
    "path": "pkg/runner/testdata/uses-nested-composite/composite_action2/action.yml",
    "content": "---\nname: \"Test Composite Action\"\ndescription: \"Test action uses composite\"\n\ninputs:\n  test_input_optional:\n    description: Test\n\nruns:\n  using: \"composite\"\n  steps:\n  - uses: actions/setup-node@v3\n    with:\n      node-version: '16'\n  - run: |\n      console.log(process.version);\n      console.log(\"Hi from node\");\n      console.log(\"${{ inputs.test_input_optional }}\");\n      if(\"${{ inputs.test_input_optional }}\" !== \"Test\") {\n        console.log(\"Invalid input test_input_optional expected \\\"Test\\\" as value\");\n        process.exit(1);\n      }\n      if(!process.version.startsWith('v16')) {\n        console.log(\"Expected node v16, but got \" + process.version);\n        process.exit(1);\n      }\n    shell: node {0}\n  - uses: ./uses-composite/composite_action\n    id: composite\n    with:\n      test_input_required: 'test_input_required_value'\n      test_input_optional: 'test_input_optional_value'\n      test_input_optional_with_default_overriden: 'test_input_optional_with_default_overriden'\n      test_input_required_with_default: 'test_input_optional_value'\n      test_input_required_with_default_overriden: 'test_input_required_with_default_overriden'\n      secret_input: ${{inputs.test_input_optional}}\n    env:\n      secret_input: ${{inputs.test_input_optional}}\n  - run: |\n      echo \"steps.composite.outputs.test_output=${{ steps.composite.outputs.test_output }}\"\n      [[ \"${{steps.composite.outputs.test_output == 'test_output_value'}}\" = \"true\" ]] || exit 1\n    shell: bash\n  - run: |\n      echo \"steps.composite.outputs.secret_output=${{ steps.composite.outputs.secret_output }}\"\n      [[ \"${{steps.composite.outputs.secret_output == format('{0}/{0}', inputs.test_input_optional)}}\" = \"true\" ]] || exit 1\n    shell: bash\n  # Now test again with default values\n  - name: ./uses-composite/composite_action with defaults\n    uses: ./uses-composite/composite_action\n    id: composite2\n    with:\n      test_input_required: 'test_input_required_value'\n      test_input_optional_with_default_overriden: 'test_input_optional_with_default_overriden'\n      test_input_required_with_default_overriden: 'test_input_required_with_default_overriden'\n\n  - run: |\n      echo \"steps.composite2.outputs.test_output=${{ steps.composite2.outputs.test_output }}\"\n      [[ \"${{steps.composite2.outputs.test_output == 'test_output_value'}}\" = \"true\" ]] || exit 1\n    shell: bash\n  - run: |\n      echo \"steps.composite.outputs.secret_output=$COMPOSITE_ACTION_ENV_OUTPUT\"\n      [[ \"${{env.COMPOSITE_ACTION_ENV_OUTPUT == 'my test value' }}\" = \"true\" ]] || exit 1\n    shell: bash\n"
  },
  {
    "path": "pkg/runner/testdata/uses-nested-composite/push.yml",
    "content": "name: uses-nested-composite\non: push\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: ./uses-nested-composite/composite_action2\n      with:\n        test_input_optional: Test\n    - run: |\n        echo \"steps.composite.outputs.secret_output=$COMPOSITE_ACTION_ENV_OUTPUT\"\n        [[ \"${{env.COMPOSITE_ACTION_ENV_OUTPUT == 'my test value' }}\" = \"true\" ]] || exit 1\n      shell: bash"
  },
  {
    "path": "pkg/runner/testdata/uses-workflow/local-workflow.yml",
    "content": "name: local-reusable-workflows\non: pull_request\n\njobs:\n  reusable-workflow:\n    uses: ./.github/workflows/local-reusable-workflow.yml\n    with:\n      string_required: string\n      bool_required: ${{ true }}\n      number_required: 1\n    secrets:\n      secret: keep_it_private\n\n  reusable-workflow-with-inherited-secrets:\n    uses: ./.github/workflows/local-reusable-workflow.yml\n    with:\n      string_required: string\n      bool_required: ${{ true }}\n      number_required: 1\n    secrets: inherit\n\n  reusable-workflow-with-on-string-notation:\n    uses: ./.github/workflows/local-reusable-workflow-no-inputs-string.yml\n\n  reusable-workflow-with-on-array-notation:\n    uses: ./.github/workflows/local-reusable-workflow-no-inputs-array.yml\n\n  output-test:\n    runs-on: ubuntu-latest\n    needs:\n      - reusable-workflow\n      - reusable-workflow-with-inherited-secrets\n    steps:\n      - name: output with secrets map\n        run: |\n          echo reusable-workflow.output=${{ needs.reusable-workflow.outputs.output }}\n          [[ \"${{ needs.reusable-workflow.outputs.output == 'string' }}\" = \"true\" ]] || exit 1\n\n      - name: output with inherited secrets\n        run: |\n          echo reusable-workflow-with-inherited-secrets.output=${{ needs.reusable-workflow-with-inherited-secrets.outputs.output }}\n          [[ \"${{ needs.reusable-workflow-with-inherited-secrets.outputs.output == 'string' }}\" = \"true\" ]] || exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/uses-workflow/push.yml",
    "content": "on: push\n\njobs:\n  reusable-workflow:\n    uses: nektos/act-test-actions/.github/workflows/reusable-workflow.yml@main\n    with:\n      string_required: string\n      bool_required: ${{ true }}\n      number_required: 1\n    secrets:\n      secret: keep_it_private\n\n  reusable-workflow-with-inherited-secrets:\n    uses: nektos/act-test-actions/.github/workflows/reusable-workflow.yml@main\n    with:\n      string_required: string\n      bool_required: ${{ true }}\n      number_required: 1\n    secrets: inherit\n\n  output-test:\n    runs-on: ubuntu-latest\n    needs:\n      - reusable-workflow\n      - reusable-workflow-with-inherited-secrets\n    steps:\n      - name: output with secrets map\n        run: |\n          echo reusable-workflow.output=${{ needs.reusable-workflow.outputs.output }}\n          [[ \"${{ needs.reusable-workflow.outputs.output == 'string' }}\" = \"true\" ]] || exit 1\n\n      - name: output with inherited secrets\n        run: |\n          echo reusable-workflow-with-inherited-secrets.output=${{ needs.reusable-workflow-with-inherited-secrets.outputs.output }}\n          [[ \"${{ needs.reusable-workflow-with-inherited-secrets.outputs.output == 'string' }}\" = \"true\" ]] || exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/uses-workflow-defaults/workflow_dispatch.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    branches: [ \"main\" ]\n\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - name: Run a one-line script\n        run: echo \"✅ 🚀 ✅ hello this is from workflow main\" ${{ github.event_name }}  \n  call-reuse-w-val:\n    uses: ./.github/workflows/local-reusable-and-dispatch.yml\n    with:\n      my-val: \"passed value from main\"\n"
  },
  {
    "path": "pkg/runner/testdata/windows-add-env/action/action.yml",
    "content": "runs:\n  using: composite\n  steps:\n  - run: |\n      echo $env:GITHUB_ENV\n      echo \"kEy=n/a\" > $env:GITHUB_ENV\n    shell: pwsh"
  },
  {
    "path": "pkg/runner/testdata/windows-add-env/push.yml",
    "content": "on:\r\n  push:\r\njobs:\r\n  test:\r\n    runs-on: windows-latest\r\n    steps:\r\n    - run: |\r\n        echo $env:GITHUB_ENV\r\n        echo \"key=val\" >> $env:GITHUB_ENV\r\n        echo \"key2<<EOF\" >> $env:GITHUB_ENV\r\n        echo \"line1\" >> $env:GITHUB_ENV\r\n        echo \"line2\" >> $env:GITHUB_ENV\r\n        echo \"EOF\" >> $env:GITHUB_ENV\r\n        cat $env:GITHUB_ENV\r\n    - run: |\r\n        ls env:\r\n        if($env:key -ne 'val') {\r\n          echo \"Unexpected value for `$env:key: $env:key\"\r\n          exit 1\r\n        }\r\n        if($env:key2 -ne \"line1`nline2\") {\r\n          echo \"Unexpected value for `$env:key2: $env:key2\"\r\n          exit 1\r\n        }\r\n    - run: |\r\n        echo $env:GITHUB_ENV\r\n        # Defect missing append\r\n        echo \"KEY=test\" > $env:GITHUB_ENV\r\n        # Defect missing append, test is broken!!!\r\n        echo \"Key=expected\" > $env:GITHUB_ENV\r\n    - name: Assert GITHUB_ENV is merged case insensitive\r\n      run: exit 1\r\n      if: env.KEY != 'expected' || env.Key != 'expected' || env.key != 'expected'\r\n    - name: Assert step env is merged case insensitive\r\n      run: exit 1\r\n      if: env.KEY != 'n/a' || env.Key != 'n/a' || env.key != 'n/a'\r\n      env:\r\n        KeY: 'n/a'\r\n    - uses: actions/checkout@v3\r\n    - uses: ./windows-add-env/action\r\n    - name: Assert composite env is merged case insensitive\r\n      run: exit 1\r\n      if: env.KEY != 'n/a' || env.Key != 'n/a' || env.key != 'n/a'"
  },
  {
    "path": "pkg/runner/testdata/windows-add-env-powershell-5/action/action.yml",
    "content": "runs:\n  using: composite\n  steps:\n  - run: |\n      echo $env:GITHUB_ENV\n      echo \"kEy=n/a\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append\n    shell: powershell\n"
  },
  {
    "path": "pkg/runner/testdata/windows-add-env-powershell-5/push.yml",
    "content": "on:\r\n  push:\r\njobs:\r\n  test:\r\n    runs-on: windows-latest\r\n    steps:\r\n    - run: |\r\n        echo $env:GITHUB_ENV\r\n        echo \"key=val\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append\r\n        echo \"key2<<EOF\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append\r\n        echo \"line1\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append\r\n        echo \"line2\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append\r\n        echo \"EOF\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append\r\n        cat $env:GITHUB_ENV\r\n      shell: powershell\r\n    - run: |\r\n        ls env:\r\n        if($env:key -ne 'val') {\r\n          echo \"Unexpected value for `$env:key: $env:key\"\r\n          exit 1\r\n        }\r\n        if($env:key2 -ne \"line1`nline2\") {\r\n          echo \"Unexpected value for `$env:key2: $env:key2\"\r\n          exit 1\r\n        }\r\n      shell: powershell\r\n    - run: |\r\n        echo $env:GITHUB_ENV\r\n        echo \"KEY=test\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8\r\n        # Defect missing append, test is broken!!!\r\n        echo \"Key=expected\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8\r\n      shell: powershell\r\n    - name: Assert GITHUB_ENV is merged case insensitive\r\n      run: exit 1\r\n      if: env.KEY != 'expected' || env.Key != 'expected' || env.key != 'expected'\r\n      shell: powershell\r\n    - name: Assert step env is merged case insensitive\r\n      run: exit 1\r\n      if: env.KEY != 'n/a' || env.Key != 'n/a' || env.key != 'n/a'\r\n      env:\r\n        KeY: 'n/a'\r\n      shell: powershell\r\n    - uses: actions/checkout@v3\r\n    - uses: ./windows-add-env-powershell-5/action\r\n    - name: Assert composite env is merged case insensitive\r\n      run: exit 1\r\n      if: env.KEY != 'n/a' || env.Key != 'n/a' || env.key != 'n/a'\r\n      shell: powershell\r\n"
  },
  {
    "path": "pkg/runner/testdata/windows-prepend-path/push.yml",
    "content": "on:\r\n  push:\r\ndefaults:\r\n  run:\r\n    shell: pwsh\r\njobs:\r\n  test:\r\n    runs-on: windows-latest\r\n    steps:\r\n    - run: |\r\n        mkdir build\r\n        echo '@echo off' > build/test.cmd\r\n        echo 'echo Hi' >> build/test.cmd\r\n        mkdir build2\r\n        echo '@echo off' > build2/test2.cmd\r\n        echo 'echo test2' >> build2/test2.cmd\r\n    - run: |\r\n        echo '${{ tojson(runner) }}'\r\n        ls\r\n        echo '${{ github.workspace }}'\r\n      working-directory: ${{ github.workspace }}\\build\r\n    - run: |\r\n        echo $env:GITHUB_PATH\r\n        echo '${{ github.workspace }}\\build' > $env:GITHUB_PATH\r\n        cat $env:GITHUB_PATH\r\n    - run: |\r\n        echo $env:PATH\r\n        test\r\n    - run: |\r\n        echo \"PATH=$env:PATH;${{ github.workspace }}\\build2\" > $env:GITHUB_ENV\r\n    - run: |\r\n        echo $env:PATH\r\n        test\r\n        test2"
  },
  {
    "path": "pkg/runner/testdata/windows-prepend-path-powershell-5/push.yml",
    "content": "on:\r\n  push:\r\ndefaults:\r\n  run:\r\n    shell: powershell\r\njobs:\r\n  test:\r\n    runs-on: windows-latest\r\n    steps:\r\n    - run: |\r\n        mkdir build\r\n        echo '@echo off' | Out-File -FilePath build/test.cmd -Encoding utf8\r\n        echo 'echo Hi' | Out-File -FilePath build/test.cmd -Encoding utf8 -Append\r\n        mkdir build2\r\n        echo '@echo off' | Out-File -FilePath build/test2.cmd -Encoding utf8\r\n        echo 'echo test2' | Out-File -FilePath build/test2.cmd -Encoding utf8 -Append\r\n    - run: |\r\n        echo '${{ tojson(runner) }}'\r\n        ls\r\n        echo '${{ github.workspace }}'\r\n      working-directory: ${{ github.workspace }}\\build\r\n    - run: |\r\n        echo $env:GITHUB_PATH\r\n        echo '${{ github.workspace }}\\build' | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append\r\n        cat $env:GITHUB_PATH\r\n    - run: |\r\n        echo $env:PATH\r\n        test\r\n    - run: |\r\n        echo \"PATH=$env:PATH;${{ github.workspace }}\\build2\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append\r\n    - run: |\r\n        echo $env:PATH\r\n        test\r\n        test2"
  },
  {
    "path": "pkg/runner/testdata/windows-shell-cmd/push.yml",
    "content": "on:\r\n  push:\r\njobs:\r\n  test:\r\n    runs-on: windows-latest\r\n    steps:\r\n    - run: |\r\n        echo Hi\r\n      shell: cmd"
  },
  {
    "path": "pkg/runner/testdata/workdir/canary",
    "content": ""
  },
  {
    "path": "pkg/runner/testdata/workdir/push.yml",
    "content": "on: push\n\ndefaults:\n  run:\n    working-directory: /tmp\n\njobs:\n  workdir:\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: /root\n    steps:\n      - run: '[[ \"$(pwd)\" == \"/root\" ]]'\n\n      - run: mkdir -p \"${GITHUB_WORKSPACE}/workdir\"\n\n      - run: '[[ \"$(pwd)\" == \"${GITHUB_WORKSPACE}/workdir\" ]]'\n        working-directory: workdir\n\n  top-level-workdir:\n    runs-on: ubuntu-latest\n    steps:\n      - run: '[[ \"$(pwd)\" == \"/tmp\" ]]'\n\n  workdir-from-matrix:\n    runs-on: ubuntu-latest\n    strategy:\n      max-parallel: 1\n      matrix:\n        work_dir: [\"/tmp\", \"/root\"]\n    steps:\n      - run: '[[ \"$(pwd)\" == \"${{ matrix.work_dir }}\" ]]'\n        working-directory: ${{ matrix.work_dir }}\n"
  },
  {
    "path": "pkg/runner/testdata/workflow_call_inputs/event.json",
    "content": "{\n  \"inputs\": {\n    \"required\": \"required input\",\n    \"boolean\": \"true\"\n  }\n}\n"
  },
  {
    "path": "pkg/runner/testdata/workflow_call_inputs/workflow_call_inputs.yml",
    "content": "name: workflow_call\n\non:\n  workflow_call:\n    inputs:\n      required:\n        description: a required input\n        required: true\n      with_default:\n        description: an input with default\n        required: false\n        default: default\n      boolean:\n        description: an input of type boolean\n        required: false\n        type: boolean\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - name: test required input\n        run: |\n          echo input.required=${{ inputs.required }}\n          [[ \"${{ inputs.required }}\" = \"required input\" ]] || exit 1\n      - name: test input with default\n        run: |\n          echo input.with_default=${{ inputs.with_default }}\n          [[ \"${{ inputs.with_default }}\" = \"default\" ]] || exit 1\n      - id: boolean-test\n        name: run on boolean input\n        if: ${{ inputs.boolean == true }}\n        run: echo \"::set-output name=value::executed\"\n      - name: has boolean test?\n        run: |\n          [[ \"${{ steps.boolean-test.outputs.value }}\" = \"executed\" ]] || exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/workflow_dispatch/event.json",
    "content": "{\n  \"inputs\": {\n    \"required\": \"required input\",\n    \"boolean\": \"true\"\n  }\n}\n"
  },
  {
    "path": "pkg/runner/testdata/workflow_dispatch/workflow_dispatch.yml",
    "content": "name: workflow_dispatch\n\non:\n  workflow_dispatch:\n    inputs:\n      required:\n        description: a required input\n        required: true\n      with_default:\n        description: an input with default\n        required: false\n        default: default\n      boolean:\n        description: an input of type boolean\n        required: false\n        type: boolean\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - name: test required input\n        run: |\n          echo input.required=${{ inputs.required }}\n          [[ \"${{ inputs.required }}\" = \"required input\" ]] || exit 1\n      - name: test input with default\n        run: |\n          echo input.with_default=${{ inputs.with_default }}\n          [[ \"${{ inputs.with_default }}\" = \"default\" ]] || exit 1\n      - id: boolean-test\n        name: run on boolean input\n        if: ${{ inputs.boolean == true }}\n        run: echo \"::set-output name=value::executed\"\n      - name: has boolean test?\n        run: |\n          [[ \"${{ steps.boolean-test.outputs.value }}\" = \"executed\" ]] || exit 1\n"
  },
  {
    "path": "pkg/runner/testdata/workflow_dispatch-scalar/workflow_dispatch.yml",
    "content": "name: workflow_dispatch\n\non: workflow_dispatch\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - run: exit 0\n"
  },
  {
    "path": "pkg/runner/testdata/workflow_dispatch-scalar-composite-action/workflow_dispatch.yml",
    "content": "name: workflow_dispatch\n\non: workflow_dispatch\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - run: |\n          runs:\n            using: composite\n            steps:\n            - run: |\n                exit 0\n              shell: bash\n        shell: cp {0} action.yml\n      - uses: ./\n"
  },
  {
    "path": "pkg/runner/testdata/workflow_dispatch_no_inputs_mapping/workflow_dispatch.yml",
    "content": "name: workflow_dispatch\n\non:\n  workflow_dispatch:\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - run: exit 0\n"
  },
  {
    "path": "pkg/schema/action_schema.json",
    "content": "{\n  \"definitions\": {\n    \"action-root\": {\n      \"description\": \"Action file\",\n      \"mapping\": {\n        \"properties\": {\n          \"name\": \"string\",\n          \"description\": \"string\",\n          \"inputs\": \"inputs\",\n          \"runs\": \"runs\",\n          \"outputs\": \"outputs\"\n        },\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"any\"\n      }\n    },\n    \"inputs\": {\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"input\"\n      }\n    },\n    \"input\": {\n      \"mapping\": {\n        \"properties\": {\n          \"default\": \"input-default-context\"\n        },\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"any\"\n      }\n    },\n    \"outputs\": {\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"output-definition\"\n      }\n    },\n    \"output-definition\": {\n      \"mapping\": {\n        \"properties\": {\n          \"description\": \"string\",\n          \"value\": \"output-value\"\n        }\n      }\n    },\n    \"runs\": {\n      \"one-of\": [\"container-runs\", \"node-runs\", \"plugin-runs\", \"composite-runs\"]\n    },\n    \"container-runs\": {\n      \"mapping\": {\n        \"properties\": {\n          \"using\": \"non-empty-string\",\n          \"image\": \"non-empty-string\",\n          \"entrypoint\": \"non-empty-string\",\n          \"args\": \"container-runs-args\",\n          \"env\": \"container-runs-env\",\n          \"pre-entrypoint\": \"non-empty-string\",\n          \"pre-if\": \"non-empty-string\",\n          \"post-entrypoint\": \"non-empty-string\",\n          \"post-if\": \"non-empty-string\"\n        }\n      }\n    },\n    \"container-runs-args\": {\n      \"sequence\": {\n        \"item-type\": \"container-runs-context\"\n      }\n    },\n    \"container-runs-env\": {\n      \"context\": [\"inputs\"],\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string\"\n      }\n    },\n    \"node-runs\": {\n      \"mapping\": {\n        \"properties\": {\n          \"using\": \"non-empty-string\",\n          \"main\": \"non-empty-string\",\n          \"pre\": \"non-empty-string\",\n          \"pre-if\": \"non-empty-string\",\n          \"post\": \"non-empty-string\",\n          \"post-if\": \"non-empty-string\"\n        }\n      }\n    },\n    \"plugin-runs\": {\n      \"mapping\": {\n        \"properties\": {\n          \"plugin\": \"non-empty-string\"\n        }\n      }\n    },\n    \"composite-runs\": {\n      \"mapping\": {\n        \"properties\": {\n          \"using\": \"non-empty-string\",\n          \"steps\": \"composite-steps\"\n        }\n      }\n    },\n    \"composite-steps\": {\n      \"sequence\": {\n        \"item-type\": \"composite-step\"\n      }\n    },\n    \"composite-step\": {\n      \"one-of\": [\"run-step\", \"uses-step\"]\n    },\n    \"run-step\": {\n      \"mapping\": {\n        \"properties\": {\n          \"name\": \"string-steps-context\",\n          \"id\": \"non-empty-string\",\n          \"if\": \"step-if\",\n          \"run\": {\n            \"type\": \"string-steps-context\",\n            \"required\": true\n          },\n          \"env\": \"step-env\",\n          \"continue-on-error\": \"boolean-steps-context\",\n          \"working-directory\": \"string-steps-context\",\n          \"shell\": {\n            \"type\": \"string-steps-context\",\n            \"required\": true\n          }\n        }\n      }\n    },\n    \"uses-step\": {\n      \"mapping\": {\n        \"properties\": {\n          \"name\": \"string-steps-context\",\n          \"id\": \"non-empty-string\",\n          \"if\": \"step-if\",\n          \"uses\": {\n            \"type\": \"non-empty-string\",\n            \"required\": true\n          },\n          \"continue-on-error\": \"boolean-steps-context\",\n          \"with\": \"step-with\",\n          \"env\": \"step-env\"\n        }\n      }\n    },\n    \"container-runs-context\": {\n      \"context\": [\"inputs\"],\n      \"string\": {}\n    },\n    \"output-value\": {\n      \"context\": [\n        \"github\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"inputs\",\n        \"job\",\n        \"runner\",\n        \"env\"\n      ],\n      \"string\": {}\n    },\n    \"input-default-context\": {\n      \"context\": [\n        \"github\",\n        \"strategy\",\n        \"matrix\",\n        \"job\",\n        \"runner\",\n        \"hashFiles(1,255)\"\n      ],\n      \"string\": {}\n    },\n    \"non-empty-string\": {\n      \"string\": {\n        \"require-non-empty\": true\n      }\n    },\n    \"string-steps-context\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"string\": {}\n    },\n    \"boolean-steps-context\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"boolean\": {}\n    },\n    \"step-env\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string\"\n      }\n    },\n    \"step-if\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"always(0,0)\",\n        \"failure(0,0)\",\n        \"cancelled(0,0)\",\n        \"success(0,0)\",\n        \"hashFiles(1,255)\"\n      ],\n      \"string\": {}\n    },\n    \"step-with\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "pkg/schema/schema.go",
    "content": "package schema\n\nimport (\n\t_ \"embed\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/rhysd/actionlint\"\n\t\"gopkg.in/yaml.v3\"\n)\n\n//go:embed workflow_schema.json\nvar workflowSchema string\n\n//go:embed action_schema.json\nvar actionSchema string\n\nvar functions = regexp.MustCompile(`^([a-zA-Z0-9_]+)\\(([0-9]+),([0-9]+|MAX)\\)$`)\n\ntype Schema struct {\n\tDefinitions map[string]Definition\n}\n\nfunc (s *Schema) GetDefinition(name string) Definition {\n\tdef, ok := s.Definitions[name]\n\tif !ok {\n\t\tswitch name {\n\t\tcase \"any\":\n\t\t\treturn Definition{OneOf: &[]string{\"sequence\", \"mapping\", \"number\", \"boolean\", \"string\", \"null\"}}\n\t\tcase \"sequence\":\n\t\t\treturn Definition{Sequence: &SequenceDefinition{ItemType: \"any\"}}\n\t\tcase \"mapping\":\n\t\t\treturn Definition{Mapping: &MappingDefinition{LooseKeyType: \"any\", LooseValueType: \"any\"}}\n\t\tcase \"number\":\n\t\t\treturn Definition{Number: &NumberDefinition{}}\n\t\tcase \"string\":\n\t\t\treturn Definition{String: &StringDefinition{}}\n\t\tcase \"boolean\":\n\t\t\treturn Definition{Boolean: &BooleanDefinition{}}\n\t\tcase \"null\":\n\t\t\treturn Definition{Null: &NullDefinition{}}\n\t\t}\n\t}\n\treturn def\n}\n\ntype Definition struct {\n\tContext       []string\n\tMapping       *MappingDefinition\n\tSequence      *SequenceDefinition\n\tOneOf         *[]string `json:\"one-of\"`\n\tAllowedValues *[]string `json:\"allowed-values\"`\n\tString        *StringDefinition\n\tNumber        *NumberDefinition\n\tBoolean       *BooleanDefinition\n\tNull          *NullDefinition\n}\n\ntype MappingDefinition struct {\n\tProperties     map[string]MappingProperty\n\tLooseKeyType   string `json:\"loose-key-type\"`\n\tLooseValueType string `json:\"loose-value-type\"`\n}\n\ntype MappingProperty struct {\n\tType     string\n\tRequired bool\n}\n\nfunc (s *MappingProperty) UnmarshalJSON(data []byte) error {\n\tif json.Unmarshal(data, &s.Type) != nil {\n\t\ttype MProp MappingProperty\n\t\treturn json.Unmarshal(data, (*MProp)(s))\n\t}\n\treturn nil\n}\n\ntype SequenceDefinition struct {\n\tItemType string `json:\"item-type\"`\n}\n\ntype StringDefinition struct {\n\tConstant     string\n\tIsExpression bool `json:\"is-expression\"`\n}\n\ntype NumberDefinition struct {\n}\n\ntype BooleanDefinition struct {\n}\n\ntype NullDefinition struct {\n}\n\nfunc GetWorkflowSchema() *Schema {\n\tsh := &Schema{}\n\t_ = json.Unmarshal([]byte(workflowSchema), sh)\n\treturn sh\n}\n\nfunc GetActionSchema() *Schema {\n\tsh := &Schema{}\n\t_ = json.Unmarshal([]byte(actionSchema), sh)\n\treturn sh\n}\n\ntype Node struct {\n\tDefinition string\n\tSchema     *Schema\n\tContext    []string\n}\n\ntype FunctionInfo struct {\n\tname string\n\tmin  int\n\tmax  int\n}\n\nfunc (s *Node) checkSingleExpression(exprNode actionlint.ExprNode) error {\n\tif len(s.Context) == 0 {\n\t\tswitch exprNode.Token().Kind {\n\t\tcase actionlint.TokenKindInt:\n\t\tcase actionlint.TokenKindFloat:\n\t\tcase actionlint.TokenKindString:\n\t\t\treturn nil\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"expressions are not allowed here\")\n\t\t}\n\t}\n\n\tfuncs := s.GetFunctions()\n\n\tvar err error\n\tactionlint.VisitExprNode(exprNode, func(node, _ actionlint.ExprNode, entering bool) {\n\t\tif funcCallNode, ok := node.(*actionlint.FuncCallNode); entering && ok {\n\t\t\tfor _, v := range *funcs {\n\t\t\t\tif strings.EqualFold(funcCallNode.Callee, v.name) {\n\t\t\t\t\tif v.min > len(funcCallNode.Args) {\n\t\t\t\t\t\terr = errors.Join(err, fmt.Errorf(\"Missing parameters for %s expected >= %v got %v\", funcCallNode.Callee, v.min, len(funcCallNode.Args)))\n\t\t\t\t\t}\n\t\t\t\t\tif v.max < len(funcCallNode.Args) {\n\t\t\t\t\t\terr = errors.Join(err, fmt.Errorf(\"Too many parameters for %s expected <= %v got %v\", funcCallNode.Callee, v.max, len(funcCallNode.Args)))\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\terr = errors.Join(err, fmt.Errorf(\"Unknown Function Call %s\", funcCallNode.Callee))\n\t\t}\n\t\tif varNode, ok := node.(*actionlint.VariableNode); entering && ok {\n\t\t\tfor _, v := range s.Context {\n\t\t\t\tif strings.EqualFold(varNode.Name, v) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\terr = errors.Join(err, fmt.Errorf(\"Unknown Variable Access %s\", varNode.Name))\n\t\t}\n\t})\n\treturn err\n}\n\nfunc (s *Node) GetFunctions() *[]FunctionInfo {\n\tfuncs := &[]FunctionInfo{}\n\tAddFunction(funcs, \"contains\", 2, 2)\n\tAddFunction(funcs, \"endsWith\", 2, 2)\n\tAddFunction(funcs, \"format\", 1, 255)\n\tAddFunction(funcs, \"join\", 1, 2)\n\tAddFunction(funcs, \"startsWith\", 2, 2)\n\tAddFunction(funcs, \"toJson\", 1, 1)\n\tAddFunction(funcs, \"fromJson\", 1, 1)\n\tfor _, v := range s.Context {\n\t\ti := strings.Index(v, \"(\")\n\t\tif i == -1 {\n\t\t\tcontinue\n\t\t}\n\t\tsmatch := functions.FindStringSubmatch(v)\n\t\tif len(smatch) > 0 {\n\t\t\tfunctionName := smatch[1]\n\t\t\tminParameters, _ := strconv.ParseInt(smatch[2], 10, 32)\n\t\t\tmaxParametersRaw := smatch[3]\n\t\t\tvar maxParameters int64\n\t\t\tif strings.EqualFold(maxParametersRaw, \"MAX\") {\n\t\t\t\tmaxParameters = math.MaxInt32\n\t\t\t} else {\n\t\t\t\tmaxParameters, _ = strconv.ParseInt(maxParametersRaw, 10, 32)\n\t\t\t}\n\t\t\t*funcs = append(*funcs, FunctionInfo{\n\t\t\t\tname: functionName,\n\t\t\t\tmin:  int(minParameters),\n\t\t\t\tmax:  int(maxParameters),\n\t\t\t})\n\t\t}\n\t}\n\treturn funcs\n}\n\nfunc (s *Node) checkExpression(node *yaml.Node) (bool, error) {\n\tval := node.Value\n\thadExpr := false\n\tvar err error\n\tfor {\n\t\tif i := strings.Index(val, \"${{\"); i != -1 {\n\t\t\tval = val[i+3:]\n\t\t} else {\n\t\t\treturn hadExpr, err\n\t\t}\n\t\thadExpr = true\n\n\t\tparser := actionlint.NewExprParser()\n\t\tlexer := actionlint.NewExprLexer(val)\n\t\texprNode, parseErr := parser.Parse(lexer)\n\t\tif parseErr != nil {\n\t\t\terr = errors.Join(err, fmt.Errorf(\"%sFailed to parse: %s\", formatLocation(node), parseErr.Message))\n\t\t\tcontinue\n\t\t}\n\t\tval = val[lexer.Offset():]\n\t\tcerr := s.checkSingleExpression(exprNode)\n\t\tif cerr != nil {\n\t\t\terr = errors.Join(err, fmt.Errorf(\"%s%w\", formatLocation(node), cerr))\n\t\t}\n\t}\n}\n\nfunc AddFunction(funcs *[]FunctionInfo, s string, i1, i2 int) {\n\t*funcs = append(*funcs, FunctionInfo{\n\t\tname: s,\n\t\tmin:  i1,\n\t\tmax:  i2,\n\t})\n}\n\nfunc (s *Node) UnmarshalYAML(node *yaml.Node) error {\n\tif node != nil && node.Kind == yaml.DocumentNode {\n\t\treturn s.UnmarshalYAML(node.Content[0])\n\t}\n\tdef := s.Schema.GetDefinition(s.Definition)\n\tif s.Context == nil {\n\t\ts.Context = def.Context\n\t}\n\n\tisExpr, err := s.checkExpression(node)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif isExpr {\n\t\treturn nil\n\t}\n\tif def.Mapping != nil {\n\t\treturn s.checkMapping(node, def)\n\t} else if def.Sequence != nil {\n\t\treturn s.checkSequence(node, def)\n\t} else if def.OneOf != nil {\n\t\treturn s.checkOneOf(def, node)\n\t}\n\n\tif node.Kind != yaml.ScalarNode {\n\t\treturn fmt.Errorf(\"%sExpected a scalar got %v\", formatLocation(node), getStringKind(node.Kind))\n\t}\n\n\tif def.String != nil {\n\t\treturn s.checkString(node, def)\n\t} else if def.Number != nil {\n\t\tvar num float64\n\t\treturn node.Decode(&num)\n\t} else if def.Boolean != nil {\n\t\tvar b bool\n\t\treturn node.Decode(&b)\n\t} else if def.AllowedValues != nil {\n\t\ts := node.Value\n\t\tfor _, v := range *def.AllowedValues {\n\t\t\tif s == v {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\treturn fmt.Errorf(\"%sExpected one of %s got %s\", formatLocation(node), strings.Join(*def.AllowedValues, \",\"), s)\n\t} else if def.Null != nil {\n\t\tvar myNull *byte\n\t\treturn node.Decode(&myNull)\n\t}\n\treturn errors.ErrUnsupported\n}\n\nfunc (s *Node) checkString(node *yaml.Node, def Definition) error {\n\tval := node.Value\n\tif def.String.Constant != \"\" && def.String.Constant != val {\n\t\treturn fmt.Errorf(\"%sExpected %s got %s\", formatLocation(node), def.String.Constant, val)\n\t}\n\tif def.String.IsExpression {\n\t\tparser := actionlint.NewExprParser()\n\t\tlexer := actionlint.NewExprLexer(val + \"}}\")\n\t\texprNode, parseErr := parser.Parse(lexer)\n\t\tif parseErr != nil {\n\t\t\treturn fmt.Errorf(\"%sFailed to parse: %s\", formatLocation(node), parseErr.Message)\n\t\t}\n\t\tcerr := s.checkSingleExpression(exprNode)\n\t\tif cerr != nil {\n\t\t\treturn fmt.Errorf(\"%s%w\", formatLocation(node), cerr)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *Node) checkOneOf(def Definition, node *yaml.Node) error {\n\tvar allErrors error\n\tfor _, v := range *def.OneOf {\n\t\tsub := &Node{\n\t\t\tDefinition: v,\n\t\t\tSchema:     s.Schema,\n\t\t\tContext:    append(append([]string{}, s.Context...), s.Schema.GetDefinition(v).Context...),\n\t\t}\n\n\t\terr := sub.UnmarshalYAML(node)\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t\tallErrors = errors.Join(allErrors, fmt.Errorf(\"%sFailed to match %s: %w\", formatLocation(node), v, err))\n\t}\n\treturn allErrors\n}\n\nfunc getStringKind(k yaml.Kind) string {\n\tswitch k {\n\tcase yaml.DocumentNode:\n\t\treturn \"document\"\n\tcase yaml.SequenceNode:\n\t\treturn \"sequence\"\n\tcase yaml.MappingNode:\n\t\treturn \"mapping\"\n\tcase yaml.ScalarNode:\n\t\treturn \"scalar\"\n\tcase yaml.AliasNode:\n\t\treturn \"alias\"\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\nfunc (s *Node) checkSequence(node *yaml.Node, def Definition) error {\n\tif node.Kind != yaml.SequenceNode {\n\t\treturn fmt.Errorf(\"%sExpected a sequence got %v\", formatLocation(node), getStringKind(node.Kind))\n\t}\n\tvar allErrors error\n\tfor _, v := range node.Content {\n\t\tallErrors = errors.Join(allErrors, (&Node{\n\t\t\tDefinition: def.Sequence.ItemType,\n\t\t\tSchema:     s.Schema,\n\t\t\tContext:    append(append([]string{}, s.Context...), s.Schema.GetDefinition(def.Sequence.ItemType).Context...),\n\t\t}).UnmarshalYAML(v))\n\t}\n\treturn allErrors\n}\n\nfunc formatLocation(node *yaml.Node) string {\n\treturn fmt.Sprintf(\"Line: %v Column %v: \", node.Line, node.Column)\n}\n\nfunc (s *Node) checkMapping(node *yaml.Node, def Definition) error {\n\tif node.Kind != yaml.MappingNode {\n\t\treturn fmt.Errorf(\"%sExpected a mapping got %v\", formatLocation(node), getStringKind(node.Kind))\n\t}\n\tinsertDirective := regexp.MustCompile(`\\${{\\s*insert\\s*}}`)\n\tvar allErrors error\n\tfor i, k := range node.Content {\n\t\tif i%2 == 0 {\n\t\t\tif insertDirective.MatchString(k.Value) {\n\t\t\t\tif len(s.Context) == 0 {\n\t\t\t\t\tallErrors = errors.Join(allErrors, fmt.Errorf(\"%sinsert is not allowed here\", formatLocation(k)))\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tisExpr, err := s.checkExpression(k)\n\t\t\tif err != nil {\n\t\t\t\tallErrors = errors.Join(allErrors, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif isExpr {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvdef, ok := def.Mapping.Properties[k.Value]\n\t\t\tif !ok {\n\t\t\t\tif def.Mapping.LooseValueType == \"\" {\n\t\t\t\t\tallErrors = errors.Join(allErrors, fmt.Errorf(\"%sUnknown Property %v\", formatLocation(k), k.Value))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tvdef = MappingProperty{Type: def.Mapping.LooseValueType}\n\t\t\t}\n\n\t\t\tif err := (&Node{\n\t\t\t\tDefinition: vdef.Type,\n\t\t\t\tSchema:     s.Schema,\n\t\t\t\tContext:    append(append([]string{}, s.Context...), s.Schema.GetDefinition(vdef.Type).Context...),\n\t\t\t}).UnmarshalYAML(node.Content[i+1]); err != nil {\n\t\t\t\tallErrors = errors.Join(allErrors, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t}\n\treturn allErrors\n}\n"
  },
  {
    "path": "pkg/schema/schema_test.go",
    "content": "package schema\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"gopkg.in/yaml.v3\"\n)\n\nfunc TestAdditionalFunctions(t *testing.T) {\n\tvar node yaml.Node\n\terr := yaml.Unmarshal([]byte(`\non: push\njobs:\n  job-with-condition:\n    runs-on: self-hosted\n    if: success() || success('joba', 'jobb') || failure() || failure('joba', 'jobb') || always() || cancelled()\n    steps:\n    - run: exit 0\n`), &node)\n\tif !assert.NoError(t, err) {\n\t\treturn\n\t}\n\terr = (&Node{\n\t\tDefinition: \"workflow-root-strict\",\n\t\tSchema:     GetWorkflowSchema(),\n\t}).UnmarshalYAML(&node)\n\tassert.NoError(t, err)\n}\n\nfunc TestAdditionalFunctionsFailure(t *testing.T) {\n\tvar node yaml.Node\n\terr := yaml.Unmarshal([]byte(`\non: push\njobs:\n  job-with-condition:\n    runs-on: self-hosted\n    if: success() || success('joba', 'jobb') || failure() || failure('joba', 'jobb') || always('error')\n    steps:\n    - run: exit 0\n`), &node)\n\tif !assert.NoError(t, err) {\n\t\treturn\n\t}\n\terr = (&Node{\n\t\tDefinition: \"workflow-root-strict\",\n\t\tSchema:     GetWorkflowSchema(),\n\t}).UnmarshalYAML(&node)\n\tassert.Error(t, err)\n}\n\nfunc TestAdditionalFunctionsSteps(t *testing.T) {\n\tvar node yaml.Node\n\terr := yaml.Unmarshal([]byte(`\non: push\njobs:\n  job-with-condition:\n    runs-on: self-hosted\n    steps:\n    - run: exit 0\n      if: success() || failure() || always()\n`), &node)\n\tif !assert.NoError(t, err) {\n\t\treturn\n\t}\n\terr = (&Node{\n\t\tDefinition: \"workflow-root-strict\",\n\t\tSchema:     GetWorkflowSchema(),\n\t}).UnmarshalYAML(&node)\n\tassert.NoError(t, err)\n}\n\nfunc TestAdditionalFunctionsStepsExprSyntax(t *testing.T) {\n\tvar node yaml.Node\n\terr := yaml.Unmarshal([]byte(`\non: push\njobs:\n  job-with-condition:\n    runs-on: self-hosted\n    steps:\n    - run: exit 0\n      if: ${{ success() || failure() || always() }}\n`), &node)\n\tif !assert.NoError(t, err) {\n\t\treturn\n\t}\n\terr = (&Node{\n\t\tDefinition: \"workflow-root-strict\",\n\t\tSchema:     GetWorkflowSchema(),\n\t}).UnmarshalYAML(&node)\n\tassert.NoError(t, err)\n}\n"
  },
  {
    "path": "pkg/schema/workflow_schema.json",
    "content": "{\n  \"version\": \"workflow-v1.0\",\n  \"definitions\": {\n    \"workflow-root\": {\n      \"description\": \"A workflow file.\",\n      \"mapping\": {\n        \"properties\": {\n          \"on\": \"on\",\n          \"name\": \"workflow-name\",\n          \"description\": \"string\",\n          \"run-name\": \"run-name\",\n          \"defaults\": \"workflow-defaults\",\n          \"env\": \"workflow-env\",\n          \"permissions\": \"permissions\",\n          \"concurrency\": \"workflow-concurrency\",\n          \"jobs\": {\n            \"type\": \"jobs\",\n            \"required\": true\n          }\n        }\n      }\n    },\n    \"workflow-root-strict\": {\n      \"description\": \"Workflow file with strict validation\",\n      \"mapping\": {\n        \"properties\": {\n          \"on\": {\n            \"type\": \"on-strict\",\n            \"required\": true\n          },\n          \"name\": \"workflow-name\",\n          \"description\": \"string\",\n          \"run-name\": \"run-name\",\n          \"defaults\": \"workflow-defaults\",\n          \"env\": \"workflow-env\",\n          \"permissions\": \"permissions\",\n          \"concurrency\": \"workflow-concurrency\",\n          \"jobs\": {\n            \"type\": \"jobs\",\n            \"required\": true\n          }\n        }\n      }\n    },\n    \"workflow-name\": {\n      \"description\": \"The name of the workflow that GitHub displays on your repository's 'Actions' tab.\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#name)\",\n      \"string\": {}\n    },\n    \"run-name\": {\n      \"context\": [\"github\", \"inputs\", \"vars\"],\n      \"string\": {},\n      \"description\": \"The name for workflow runs generated from the workflow. GitHub displays the workflow run name in the list of workflow runs on your repository's 'Actions' tab.\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#run-name)\"\n    },\n    \"on\": {\n      \"description\": \"The GitHub event that triggers the workflow. Events can be a single string, array of events, array of event types, or an event configuration map that schedules a workflow or restricts the execution of a workflow to specific files, tags, or branch changes. View a full list of [events that trigger workflows](https://docs.github.com/actions/using-workflows/events-that-trigger-workflows).\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#on)\",\n      \"one-of\": [\"string\", \"sequence\", \"on-mapping\"]\n    },\n    \"on-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"workflow_call\": \"workflow-call\"\n        },\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"any\"\n      }\n    },\n    \"on-strict\": {\n      \"description\": \"The GitHub event that triggers the workflow.  Events can be a single string, array of events, array of event types, or an event configuration map that schedules a workflow or restricts the execution of a workflow to specific files, tags, or branch changes. View a full list of [events that trigger workflows](https://docs.github.com/actions/using-workflows/events-that-trigger-workflows).\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#on)\",\n      \"one-of\": [\"on-string-strict\", \"on-sequence-strict\", \"on-mapping-strict\"]\n    },\n    \"on-mapping-strict\": {\n      \"description\": \"The GitHub event that triggers the workflow.  Events can be a single string, array of events, array of event types, or an event configuration map that schedules a workflow or restricts the execution of a workflow to specific files, tags, or branch changes. View a full list of [events that trigger workflows](https://docs.github.com/actions/using-workflows/events-that-trigger-workflows).\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#on)\",\n      \"mapping\": {\n        \"properties\": {\n          \"branch_protection_rule\": \"branch-protection-rule\",\n          \"check_run\": \"check-run\",\n          \"check_suite\": \"check-suite\",\n          \"create\": \"create\",\n          \"delete\": \"delete\",\n          \"deployment\": \"deployment\",\n          \"deployment_status\": \"deployment-status\",\n          \"discussion\": \"discussion\",\n          \"discussion_comment\": \"discussion-comment\",\n          \"fork\": \"fork\",\n          \"gollum\": \"gollum\",\n          \"issue_comment\": \"issue-comment\",\n          \"issues\": \"issues\",\n          \"label\": \"label\",\n          \"merge_group\": \"merge-group\",\n          \"milestone\": \"milestone\",\n          \"page_build\": \"page-build\",\n          \"project\": \"project\",\n          \"project_card\": \"project-card\",\n          \"project_column\": \"project-column\",\n          \"public\": \"public\",\n          \"pull_request\": \"pull-request\",\n          \"pull_request_comment\": \"pull-request-comment\",\n          \"pull_request_review\": \"pull-request-review\",\n          \"pull_request_review_comment\": \"pull-request-review-comment\",\n          \"pull_request_target\": \"pull-request-target\",\n          \"push\": \"push\",\n          \"registry_package\": \"registry-package\",\n          \"release\": \"release\",\n          \"repository_dispatch\": \"repository-dispatch\",\n          \"schedule\": \"schedule\",\n          \"status\": \"status\",\n          \"watch\": \"watch\",\n          \"workflow_call\": \"workflow-call\",\n          \"workflow_dispatch\": \"workflow-dispatch\",\n          \"workflow_run\": \"workflow-run\"\n        }\n      }\n    },\n    \"on-string-strict\": {\n      \"one-of\": [\n        \"branch-protection-rule-string\",\n        \"check-run-string\",\n        \"check-suite-string\",\n        \"create-string\",\n        \"delete-string\",\n        \"deployment-string\",\n        \"deployment-status-string\",\n        \"discussion-string\",\n        \"discussion-comment-string\",\n        \"fork-string\",\n        \"gollum-string\",\n        \"issue-comment-string\",\n        \"issues-string\",\n        \"label-string\",\n        \"merge-group-string\",\n        \"milestone-string\",\n        \"page-build-string\",\n        \"project-string\",\n        \"project-card-string\",\n        \"project-column-string\",\n        \"public-string\",\n        \"pull-request-string\",\n        \"pull-request-comment-string\",\n        \"pull-request-review-string\",\n        \"pull-request-review-comment-string\",\n        \"pull-request-target-string\",\n        \"push-string\",\n        \"registry-package-string\",\n        \"release-string\",\n        \"repository-dispatch-string\",\n        \"schedule-string\",\n        \"status-string\",\n        \"watch-string\",\n        \"workflow-call-string\",\n        \"workflow-dispatch-string\",\n        \"workflow-run-string\"\n      ]\n    },\n    \"on-sequence-strict\": {\n      \"sequence\": {\n        \"item-type\": \"on-string-strict\"\n      }\n    },\n    \"branch-protection-rule-string\": {\n      \"description\": \"Runs your workflow when branch protection rules in the workflow repository are changed.\",\n      \"string\": {\n        \"constant\": \"branch_protection_rule\"\n      }\n    },\n    \"branch-protection-rule\": {\n      \"description\": \"Runs your workflow when branch protection rules in the workflow repository are changed.\",\n      \"one-of\": [\"null\", \"branch-protection-rule-mapping\"]\n    },\n    \"branch-protection-rule-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"branch-protection-rule-activity\"\n        }\n      }\n    },\n    \"branch-protection-rule-activity\": {\n      \"description\": \"The types of branch protection rule activity that trigger the workflow. Supported activity types: `created`, `edited`, `deleted`.\",\n      \"one-of\": [\n        \"branch-protection-rule-activity-type\",\n        \"branch-protection-rule-activity-types\"\n      ]\n    },\n    \"branch-protection-rule-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"branch-protection-rule-activity-type\"\n      }\n    },\n    \"branch-protection-rule-activity-type\": {\n      \"allowed-values\": [\"created\", \"edited\", \"deleted\"]\n    },\n    \"check-run-string\": {\n      \"description\": \"Runs your workflow when activity related to a check run occurs. A check run is an individual test that is part of a check suite.\",\n      \"string\": {\n        \"constant\": \"check_run\"\n      }\n    },\n    \"check-run\": {\n      \"description\": \"Runs your workflow when activity related to a check run occurs. A check run is an individual test that is part of a check suite.\",\n      \"one-of\": [\"null\", \"check-run-mapping\"]\n    },\n    \"check-run-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"check-run-activity\"\n        }\n      }\n    },\n    \"check-run-activity\": {\n      \"description\": \"The types of check run activity that trigger the workflow. Supported activity types: `created`, `rerequested`, `completed`, `requested_action`.\",\n      \"one-of\": [\"check-run-activity-type\", \"check-run-activity-types\"]\n    },\n    \"check-run-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"check-run-activity-type\"\n      }\n    },\n    \"check-run-activity-type\": {\n      \"allowed-values\": [\n        \"completed\",\n        \"created\",\n        \"rerequested\",\n        \"requested_action\"\n      ]\n    },\n    \"check-suite-string\": {\n      \"description\": \"Runs your workflow when check suite activity occurs. A check suite is a collection of the check runs created for a specific commit. Check suites summarize the status and conclusion of the check runs that are in the suite.\",\n      \"string\": {\n        \"constant\": \"check_suite\"\n      }\n    },\n    \"check-suite\": {\n      \"description\": \"Runs your workflow when check suite activity occurs. A check suite is a collection of the check runs created for a specific commit. Check suites summarize the status and conclusion of the check runs that are in the suite.\",\n      \"one-of\": [\"null\", \"check-suite-mapping\"]\n    },\n    \"check-suite-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"check-suite-activity\"\n        }\n      }\n    },\n    \"check-suite-activity\": {\n      \"description\": \"The types of check suite activity that trigger the workflow. Supported activity types: `completed`.\",\n      \"one-of\": [\"check-suite-activity-type\", \"check-suite-activity-types\"]\n    },\n    \"check-suite-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"check-suite-activity-type\"\n      }\n    },\n    \"check-suite-activity-type\": {\n      \"allowed-values\": [\"completed\"]\n    },\n    \"create-string\": {\n      \"description\": \"Runs your workflow when someone creates a Git reference (Git branch or tag) in the workflow's repository.\",\n      \"string\": {\n        \"constant\": \"create\"\n      }\n    },\n    \"create\": {\n      \"description\": \"Runs your workflow when someone creates a Git reference (Git branch or tag) in the workflow's repository.\",\n      \"null\": {}\n    },\n    \"delete-string\": {\n      \"description\": \"Runs your workflow when someone deletes a Git reference (Git branch or tag) in the workflow's repository.\",\n      \"string\": {\n        \"constant\": \"delete\"\n      }\n    },\n    \"delete\": {\n      \"description\": \"Runs your workflow when someone deletes a Git reference (Git branch or tag) in the workflow's repository.\",\n      \"null\": {}\n    },\n    \"deployment-string\": {\n      \"description\": \"Runs your workflow when someone creates a deployment in the workflow's repository. Deployments created with a commit SHA may not have a Git ref.\",\n      \"string\": {\n        \"constant\": \"deployment\"\n      }\n    },\n    \"deployment\": {\n      \"description\": \"Runs your workflow when someone creates a deployment in the workflow's repository. Deployments created with a commit SHA may not have a Git ref.\",\n      \"null\": {}\n    },\n    \"deployment-status-string\": {\n      \"description\": \"Runs your workflow when a third party provides a deployment status. Deployments created with a commit SHA may not have a Git ref.\",\n      \"string\": {\n        \"constant\": \"deployment_status\"\n      }\n    },\n    \"deployment-status\": {\n      \"description\": \"Runs your workflow when a third party provides a deployment status. Deployments created with a commit SHA may not have a Git ref.\",\n      \"null\": {}\n    },\n    \"discussion-string\": {\n      \"description\": \"Runs your workflow when a discussion in the workflow's repository is created or modified. For activity related to comments on a discussion, use the `discussion_comment` event.\",\n      \"string\": {\n        \"constant\": \"discussion\"\n      }\n    },\n    \"discussion\": {\n      \"description\": \"Runs your workflow when a discussion in the workflow's repository is created or modified. For activity related to comments on a discussion, use the `discussion_comment` event.\",\n      \"one-of\": [\"null\", \"discussion-mapping\"]\n    },\n    \"discussion-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"discussion-activity\"\n        }\n      }\n    },\n    \"discussion-activity\": {\n      \"description\": \"The types of discussion activity that trigger the workflow. Supported activity types: `created`, `edited`, `deleted`, `transferred`, `pinned`, `unpinned`, `labeled`, `unlabeled`, `locked`, `unlocked`, `category_changed`, `answered`, `unanswered`.\",\n      \"one-of\": [\"discussion-activity-type\", \"discussion-activity-types\"]\n    },\n    \"discussion-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"discussion-activity-type\"\n      }\n    },\n    \"discussion-activity-type\": {\n      \"allowed-values\": [\n        \"created\",\n        \"edited\",\n        \"deleted\",\n        \"transferred\",\n        \"pinned\",\n        \"unpinned\",\n        \"labeled\",\n        \"unlabeled\",\n        \"locked\",\n        \"unlocked\",\n        \"category_changed\",\n        \"answered\",\n        \"unanswered\"\n      ]\n    },\n    \"discussion-comment-string\": {\n      \"description\": \"Runs your workflow when a comment on a discussion in the workflow's repository is created or modified. For activity related to a discussion as opposed to comments on the discussion, use the `discussion` event.\",\n      \"string\": {\n        \"constant\": \"discussion_comment\"\n      }\n    },\n    \"discussion-comment\": {\n      \"description\": \"Runs your workflow when a comment on a discussion in the workflow's repository is created or modified. For activity related to a discussion as opposed to comments on the discussion, use the `discussion` event.\",\n      \"one-of\": [\"null\", \"discussion-comment-mapping\"]\n    },\n    \"discussion-comment-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"discussion-comment-activity\"\n        }\n      }\n    },\n    \"discussion-comment-activity\": {\n      \"description\": \"The types of discussion comment activity that trigger the workflow. Supported activity types: `created`, `edited`, `deleted`.\",\n      \"one-of\": [\n        \"discussion-comment-activity-type\",\n        \"discussion-comment-activity-types\"\n      ]\n    },\n    \"discussion-comment-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"discussion-comment-activity-type\"\n      }\n    },\n    \"discussion-comment-activity-type\": {\n      \"allowed-values\": [\"created\", \"edited\", \"deleted\"]\n    },\n    \"fork-string\": {\n      \"description\": \"Runs your workflow when someone forks a repository.\",\n      \"string\": {\n        \"constant\": \"fork\"\n      }\n    },\n    \"fork\": {\n      \"description\": \"Runs your workflow when someone forks a repository.\",\n      \"null\": {}\n    },\n    \"gollum-string\": {\n      \"description\": \"Runs your workflow when someone creates or updates a Wiki page.\",\n      \"string\": {\n        \"constant\": \"gollum\"\n      }\n    },\n    \"gollum\": {\n      \"description\": \"Runs your workflow when someone creates or updates a Wiki page.\",\n      \"null\": {}\n    },\n    \"issue-comment-string\": {\n      \"description\": \"Runs your workflow when an issue or pull request comment is created, edited, or deleted.\",\n      \"string\": {\n        \"constant\": \"issue_comment\"\n      }\n    },\n    \"issue-comment\": {\n      \"description\": \"Runs your workflow when an issue or pull request comment is created, edited, or deleted.\",\n      \"one-of\": [\"null\", \"issue-comment-mapping\"]\n    },\n    \"issue-comment-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"issue-comment-activity\"\n        }\n      }\n    },\n    \"issue-comment-activity\": {\n      \"description\": \"The types of issue comment activity that trigger the workflow. Supported activity types: `created`, `edited`, `deleted`.\",\n      \"one-of\": [\"issue-comment-activity-type\", \"issue-comment-activity-types\"]\n    },\n    \"issue-comment-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"issue-comment-activity-type\"\n      }\n    },\n    \"issue-comment-activity-type\": {\n      \"allowed-values\": [\"created\", \"edited\", \"deleted\"]\n    },\n    \"issues-string\": {\n      \"description\": \"Runs your workflow when an issue in the workflow's repository is created or modified. For activity related to comments in an issue, use the `issue_comment` event.\",\n      \"string\": {\n        \"constant\": \"issues\"\n      }\n    },\n    \"issues\": {\n      \"description\": \"Runs your workflow when an issue in the workflow's repository is created or modified. For activity related to comments in an issue, use the `issue_comment` event.\",\n      \"one-of\": [\"null\", \"issues-mapping\"]\n    },\n    \"issues-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"issues-activity\"\n        }\n      }\n    },\n    \"issues-activity\": {\n      \"description\": \"The types of issue activity that trigger the workflow. Supported activity types: `opened`, `edited`, `deleted`, `transferred`, `pinned`, `unpinned`, `closed`, `reopened`, `assigned`, `unassigned`, `labeled`, `unlabeled`, `locked`, `unlocked`, `milestoned`, `demilestoned`.\",\n      \"one-of\": [\"issues-activity-type\", \"issues-activity-types\"]\n    },\n    \"issues-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"issues-activity-type\"\n      }\n    },\n    \"issues-activity-type\": {\n      \"allowed-values\": [\n        \"opened\",\n        \"edited\",\n        \"deleted\",\n        \"transferred\",\n        \"pinned\",\n        \"unpinned\",\n        \"closed\",\n        \"reopened\",\n        \"assigned\",\n        \"unassigned\",\n        \"labeled\",\n        \"unlabeled\",\n        \"locked\",\n        \"unlocked\",\n        \"milestoned\",\n        \"demilestoned\"\n      ]\n    },\n    \"label-string\": {\n      \"description\": \"Runs your workflow when a label in your workflow's repository is created or modified.\",\n      \"string\": {\n        \"constant\": \"label\"\n      }\n    },\n    \"label\": {\n      \"description\": \"Runs your workflow when a label in your workflow's repository is created or modified.\",\n      \"one-of\": [\"null\", \"label-mapping\"]\n    },\n    \"label-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"label-activity\"\n        }\n      }\n    },\n    \"label-activity\": {\n      \"description\": \"The types of label activity that trigger the workflow. Supported activity types: `created`, `edited`, `deleted`.\",\n      \"one-of\": [\"label-activity-type\", \"label-activity-types\"]\n    },\n    \"label-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"label-activity-type\"\n      }\n    },\n    \"label-activity-type\": {\n      \"allowed-values\": [\"created\", \"edited\", \"deleted\"]\n    },\n    \"merge-group-string\": {\n      \"description\": \"Runs your workflow when a pull request is added to a merge queue, which adds the pull request to a merge group.\",\n      \"string\": {\n        \"constant\": \"merge_group\"\n      }\n    },\n    \"merge-group\": {\n      \"description\": \"Runs your workflow when a pull request is added to a merge queue, which adds the pull request to a merge group.\",\n      \"one-of\": [\"null\", \"merge-group-mapping\"]\n    },\n    \"merge-group-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"merge-group-activity\",\n          \"branches\": \"event-branches\",\n          \"branches-ignore\": \"event-branches-ignore\"\n        }\n      }\n    },\n    \"merge-group-activity\": {\n      \"description\": \"The types of merge group activity that trigger the workflow. Supported activity types: `checks_requested`.\",\n      \"one-of\": [\"merge-group-activity-type\", \"merge-group-activity-types\"]\n    },\n    \"merge-group-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"merge-group-activity-type\"\n      }\n    },\n    \"merge-group-activity-type\": {\n      \"allowed-values\": [\"checks_requested\"]\n    },\n    \"milestone-string\": {\n      \"description\": \"Runs your workflow when a milestone in the workflow's repository is created or modified.\",\n      \"string\": {\n        \"constant\": \"milestone\"\n      }\n    },\n    \"milestone\": {\n      \"description\": \"Runs your workflow when a milestone in the workflow's repository is created or modified.\",\n      \"one-of\": [\"null\", \"milestone-mapping\"]\n    },\n    \"milestone-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"milestone-activity\"\n        }\n      }\n    },\n    \"milestone-activity\": {\n      \"description\": \"The types of milestone activity that trigger the workflow. Supported activity types: `created`, `closed`, `opened`, `edited`, `deleted`.\",\n      \"one-of\": [\"milestone-activity-type\", \"milestone-activity-types\"]\n    },\n    \"milestone-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"milestone-activity-type\"\n      }\n    },\n    \"milestone-activity-type\": {\n      \"allowed-values\": [\"created\", \"closed\", \"opened\", \"edited\", \"deleted\"]\n    },\n    \"page-build-string\": {\n      \"description\": \"Runs your workflow when someone pushes to a branch that is the publishing source for GitHub Pages, if GitHub Pages is enabled for the repository.\",\n      \"string\": {\n        \"constant\": \"page_build\"\n      }\n    },\n    \"page-build\": {\n      \"description\": \"Runs your workflow when someone pushes to a branch that is the publishing source for GitHub Pages, if GitHub Pages is enabled for the repository.\",\n      \"null\": {}\n    },\n    \"project-string\": {\n      \"description\": \"Runs your workflow when a project board is created or modified. For activity related to cards or columns in a project board, use the `project_card` or `project_column` events instead.\",\n      \"string\": {\n        \"constant\": \"project\"\n      }\n    },\n    \"project\": {\n      \"description\": \"Runs your workflow when a project board is created or modified. For activity related to cards or columns in a project board, use the `project_card` or `project_column` events instead.\",\n      \"one-of\": [\"null\", \"project-mapping\"]\n    },\n    \"project-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"project-activity\"\n        }\n      }\n    },\n    \"project-activity\": {\n      \"description\": \"The types of project activity that trigger the workflow. Supported activity types: `created`, `closed`, `reopened`, `edited`, `deleted`.\",\n      \"one-of\": [\"project-activity-type\", \"project-activity-types\"]\n    },\n    \"project-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"project-activity-type\"\n      }\n    },\n    \"project-activity-type\": {\n      \"allowed-values\": [\"created\", \"closed\", \"reopened\", \"edited\", \"deleted\"]\n    },\n    \"project-card-string\": {\n      \"description\": \"Runs your workflow when a card on a project board is created or modified. For activity related to project boards or columns in a project board, use the `project` or `project_column` event instead.\",\n      \"string\": {\n        \"constant\": \"project_card\"\n      }\n    },\n    \"project-card\": {\n      \"description\": \"Runs your workflow when a card on a project board is created or modified. For activity related to project boards or columns in a project board, use the `project` or `project_column` event instead.\",\n      \"one-of\": [\"null\", \"project-card-mapping\"]\n    },\n    \"project-card-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"project-card-activity\"\n        }\n      }\n    },\n    \"project-card-activity\": {\n      \"description\": \"The types of project card activity that trigger the workflow. Supported activity types: `created`, `moved`, `converted`, `edited`, `deleted`.\",\n      \"one-of\": [\"project-card-activity-type\", \"project-card-activity-types\"]\n    },\n    \"project-card-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"project-card-activity-type\"\n      }\n    },\n    \"project-card-activity-type\": {\n      \"allowed-values\": [\"created\", \"moved\", \"converted\", \"edited\", \"deleted\"]\n    },\n    \"project-column-string\": {\n      \"description\": \"Runs your workflow when a column on a project board is created or modified. For activity related to project boards or cards in a project board, use the `project` or `project_card` event instead.\",\n      \"string\": {\n        \"constant\": \"project_column\"\n      }\n    },\n    \"project-column\": {\n      \"description\": \"Runs your workflow when a column on a project board is created or modified. For activity related to project boards or cards in a project board, use the `project` or `project_card` event instead.\",\n      \"one-of\": [\"null\", \"project-column-mapping\"]\n    },\n    \"project-column-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"project-column-activity\"\n        }\n      }\n    },\n    \"project-column-activity\": {\n      \"description\": \"The types of project column activity that trigger the workflow. Supported activity types: `created`, `updated`, `moved`, `deleted`.\",\n      \"one-of\": [\n        \"project-column-activity-type\",\n        \"project-column-activity-types\"\n      ]\n    },\n    \"project-column-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"project-column-activity-type\"\n      }\n    },\n    \"project-column-activity-type\": {\n      \"allowed-values\": [\"created\", \"updated\", \"moved\", \"deleted\"]\n    },\n    \"public-string\": {\n      \"description\": \"Runs your workflow when your workflow's repository changes from private to public.\",\n      \"string\": {\n        \"constant\": \"public\"\n      }\n    },\n    \"public\": {\n      \"description\": \"Runs your workflow when your workflow's repository changes from private to public.\",\n      \"null\": {}\n    },\n    \"pull-request-string\": {\n      \"description\": \"Runs your workflow when activity on a pull request in the workflow's repository occurs. If no activity types are specified, the workflow runs when a pull request is opened, reopened, or when the head branch of the pull request is updated.\",\n      \"string\": {\n        \"constant\": \"pull_request\"\n      }\n    },\n    \"pull-request\": {\n      \"description\": \"Runs your workflow when activity on a pull request in the workflow's repository occurs. If no activity types are specified, the workflow runs when a pull request is opened, reopened, or when the head branch of the pull request is updated.\",\n      \"one-of\": [\"null\", \"pull-request-mapping\"]\n    },\n    \"pull-request-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"pull-request-activity\",\n          \"branches\": \"event-branches\",\n          \"branches-ignore\": \"event-branches-ignore\",\n          \"paths\": \"event-paths\",\n          \"paths-ignore\": \"event-paths-ignore\"\n        }\n      }\n    },\n    \"pull-request-activity\": {\n      \"description\": \"The types of pull request activity that trigger the workflow. Supported activity types: `assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `closed`, `reopened`, `synchronize`, `converted_to_draft`, `ready_for_review`, `locked`, `unlocked`, `review_requested`, `review_request_removed`, `auto_merge_enabled`, `auto_merge_disabled`.\",\n      \"one-of\": [\"pull-request-activity-type\", \"pull-request-activity-types\"]\n    },\n    \"pull-request-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"pull-request-activity-type\"\n      }\n    },\n    \"pull-request-activity-type\": {\n      \"allowed-values\": [\n        \"assigned\",\n        \"unassigned\",\n        \"labeled\",\n        \"unlabeled\",\n        \"opened\",\n        \"edited\",\n        \"closed\",\n        \"reopened\",\n        \"synchronize\",\n        \"converted_to_draft\",\n        \"ready_for_review\",\n        \"locked\",\n        \"unlocked\",\n        \"review_requested\",\n        \"review_request_removed\",\n        \"auto_merge_enabled\",\n        \"auto_merge_disabled\"\n      ]\n    },\n    \"pull-request-comment-string\": {\n      \"description\": \"Please use the `issue_comment` event instead.\",\n      \"string\": {\n        \"constant\": \"pull_request_comment\"\n      }\n    },\n    \"pull-request-comment\": {\n      \"description\": \"Please use the `issue_comment` event instead.\",\n      \"one-of\": [\"null\", \"issue-comment-mapping\"]\n    },\n    \"pull-request-review-string\": {\n      \"description\": \"Runs your workflow when a pull request review is submitted, edited, or dismissed. A pull request review is a group of pull request review comments in addition to a body comment and a state. For activity related to pull request review comments or pull request comments, use the `pull_request_review_comment` or `issue_comment` events instead.\",\n      \"string\": {\n        \"constant\": \"pull_request_review\"\n      }\n    },\n    \"pull-request-review\": {\n      \"description\": \"Runs your workflow when a pull request review is submitted, edited, or dismissed. A pull request review is a group of pull request review comments in addition to a body comment and a state. For activity related to pull request review comments or pull request comments, use the `pull_request_review_comment` or `issue_comment` events instead.\",\n      \"one-of\": [\"null\", \"pull-request-review-mapping\"]\n    },\n    \"pull-request-review-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"pull-request-review-activity\"\n        }\n      }\n    },\n    \"pull-request-review-activity\": {\n      \"description\": \"The types of pull request review activity that trigger the workflow. Supported activity types: `submitted`, `edited`, `dismissed`.\",\n      \"one-of\": [\n        \"pull-request-review-activity-type\",\n        \"pull-request-review-activity-types\"\n      ]\n    },\n    \"pull-request-review-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"pull-request-review-activity-type\"\n      }\n    },\n    \"pull-request-review-activity-type\": {\n      \"allowed-values\": [\"submitted\", \"edited\", \"dismissed\"]\n    },\n    \"pull-request-review-comment-string\": {\n      \"description\": \"\",\n      \"string\": {\n        \"constant\": \"pull_request_review_comment\"\n      }\n    },\n    \"pull-request-review-comment\": {\n      \"description\": \"\",\n      \"one-of\": [\"null\", \"pull-request-review-comment-mapping\"]\n    },\n    \"pull-request-review-comment-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"pull-request-review-comment-activity\"\n        }\n      }\n    },\n    \"pull-request-review-comment-activity\": {\n      \"description\": \"The types of pull request review comment activity that trigger the workflow. Supported activity types: `created`, `edited`, `deleted`.\",\n      \"one-of\": [\n        \"pull-request-review-comment-activity-type\",\n        \"pull-request-review-comment-activity-types\"\n      ]\n    },\n    \"pull-request-review-comment-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"pull-request-review-comment-activity-type\"\n      }\n    },\n    \"pull-request-review-comment-activity-type\": {\n      \"allowed-values\": [\"created\", \"edited\", \"deleted\"]\n    },\n    \"pull-request-target-string\": {\n      \"description\": \"Runs your workflow when activity on a pull request in the workflow's repository occurs. If no activity types are specified, the workflow runs when a pull request is opened, reopened, or when the head branch of the pull request is updated.\\n\\nThis event runs in the context of the base of the pull request, rather than in the context of the merge commit, as the `pull_request` event does. This prevents execution of unsafe code from the head of the pull request that could alter your repository or steal any secrets you use in your workflow. This event allows your workflow to do things like label or comment on pull requests from forks. Avoid using this event if you need to build or run code from the pull request.\",\n      \"string\": {\n        \"constant\": \"pull_request_target\"\n      }\n    },\n    \"pull-request-target\": {\n      \"description\": \"Runs your workflow when activity on a pull request in the workflow's repository occurs. If no activity types are specified, the workflow runs when a pull request is opened, reopened, or when the head branch of the pull request is updated.\\n\\nThis event runs in the context of the base of the pull request, rather than in the context of the merge commit, as the `pull_request` event does. This prevents execution of unsafe code from the head of the pull request that could alter your repository or steal any secrets you use in your workflow. This event allows your workflow to do things like label or comment on pull requests from forks. Avoid using this event if you need to build or run code from the pull request.\",\n      \"one-of\": [\"null\", \"pull-request-target-mapping\"]\n    },\n    \"pull-request-target-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"pull-request-target-activity\",\n          \"branches\": \"event-branches\",\n          \"branches-ignore\": \"event-branches-ignore\",\n          \"paths\": \"event-paths\",\n          \"paths-ignore\": \"event-paths-ignore\"\n        }\n      }\n    },\n    \"pull-request-target-activity\": {\n      \"description\": \"The types of pull request activity that trigger the workflow. Supported activity types: `assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `closed`, `reopened`, `synchronize`, `converted_to_draft`, `ready_for_review`, `locked`, `unlocked`, `review_requested`, `review_request_removed`, `auto_merge_enabled`, `auto_merge_disabled`.\",\n      \"one-of\": [\n        \"pull-request-target-activity-type\",\n        \"pull-request-target-activity-types\"\n      ]\n    },\n    \"pull-request-target-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"pull-request-target-activity-type\"\n      }\n    },\n    \"pull-request-target-activity-type\": {\n      \"allowed-values\": [\n        \"assigned\",\n        \"unassigned\",\n        \"labeled\",\n        \"unlabeled\",\n        \"opened\",\n        \"edited\",\n        \"closed\",\n        \"reopened\",\n        \"synchronize\",\n        \"converted_to_draft\",\n        \"ready_for_review\",\n        \"locked\",\n        \"unlocked\",\n        \"review_requested\",\n        \"review_request_removed\",\n        \"auto_merge_enabled\",\n        \"auto_merge_disabled\"\n      ]\n    },\n    \"push-string\": {\n      \"description\": \"Runs your workflow when you push a commit or tag.\",\n      \"string\": {\n        \"constant\": \"push\"\n      }\n    },\n    \"push\": {\n      \"description\": \"Runs your workflow when you push a commit or tag.\",\n      \"one-of\": [\"null\", \"push-mapping\"]\n    },\n    \"push-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"branches\": \"event-branches\",\n          \"branches-ignore\": \"event-branches-ignore\",\n          \"tags\": \"event-tags\",\n          \"tags-ignore\": \"event-tags-ignore\",\n          \"paths\": \"event-paths\",\n          \"paths-ignore\": \"event-paths-ignore\"\n        }\n      }\n    },\n    \"registry-package-string\": {\n      \"description\": \"Runs your workflow when activity related to GitHub Packages occurs in your repository.\",\n      \"string\": {\n        \"constant\": \"registry_package\"\n      }\n    },\n    \"registry-package\": {\n      \"description\": \"Runs your workflow when activity related to GitHub Packages occurs in your repository.\",\n      \"one-of\": [\"null\", \"registry-package-mapping\"]\n    },\n    \"registry-package-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"registry-package-activity\"\n        }\n      }\n    },\n    \"registry-package-activity\": {\n      \"description\": \"The types of registry package activity that trigger the workflow. Supported activity types: `published`, `updated`.\",\n      \"one-of\": [\n        \"registry-package-activity-type\",\n        \"registry-package-activity-types\"\n      ]\n    },\n    \"registry-package-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"registry-package-activity-type\"\n      }\n    },\n    \"registry-package-activity-type\": {\n      \"allowed-values\": [\"published\", \"updated\"]\n    },\n    \"release-string\": {\n      \"description\": \"Runs your workflow when release activity in your repository occurs.\",\n      \"string\": {\n        \"constant\": \"release\"\n      }\n    },\n    \"release\": {\n      \"description\": \"Runs your workflow when release activity in your repository occurs.\",\n      \"one-of\": [\"null\", \"release-mapping\"]\n    },\n    \"release-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"release-activity\"\n        }\n      }\n    },\n    \"release-activity\": {\n      \"description\": \"The types of release activity that trigger the workflow. Supported activity types: `published`, `unpublished`, `created`, `edited`, `deleted`, `prereleased`, `released`.\",\n      \"one-of\": [\"release-activity-type\", \"release-activity-types\"]\n    },\n    \"release-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"release-activity-type\"\n      }\n    },\n    \"release-activity-type\": {\n      \"allowed-values\": [\n        \"published\",\n        \"unpublished\",\n        \"created\",\n        \"edited\",\n        \"deleted\",\n        \"prereleased\",\n        \"released\"\n      ]\n    },\n    \"schedule-string\": {\n      \"description\": \"The `schedule` event allows you to trigger a workflow at a scheduled time.\\n\\nYou can schedule a workflow to run at specific UTC times using POSIX cron syntax. Scheduled workflows run on the latest commit on the default or base branch. The shortest interval you can run scheduled workflows is once every 5 minutes. GitHub Actions does not support the non-standard syntax `@yearly`, `@monthly`, `@weekly`, `@daily`, `@hourly`, and `@reboot`.\",\n      \"string\": {\n        \"constant\": \"schedule\"\n      }\n    },\n    \"schedule\": {\n      \"description\": \"The `schedule` event allows you to trigger a workflow at a scheduled time.\\n\\nYou can schedule a workflow to run at specific UTC times using POSIX cron syntax. Scheduled workflows run on the latest commit on the default or base branch. The shortest interval you can run scheduled workflows is once every 5 minutes. GitHub Actions does not support the non-standard syntax `@yearly`, `@monthly`, `@weekly`, `@daily`, `@hourly`, and `@reboot`.\",\n      \"sequence\": {\n        \"item-type\": \"cron-mapping\"\n      }\n    },\n    \"status-string\": {\n      \"description\": \"Runs your workflow when the status of a Git commit changes. For example, commits can be marked as `error`, `failure`, `pending`, or `success`. If you want to provide more details about the status change, you may want to use the `check_run` event.\",\n      \"string\": {\n        \"constant\": \"status\"\n      }\n    },\n    \"status\": {\n      \"description\": \"Runs your workflow when the status of a Git commit changes. For example, commits can be marked as `error`, `failure`, `pending`, or `success`. If you want to provide more details about the status change, you may want to use the `check_run` event.\",\n      \"null\": {}\n    },\n    \"watch-string\": {\n      \"description\": \"Runs your workflow when the workflow's repository is starred.\",\n      \"string\": {\n        \"constant\": \"watch\"\n      }\n    },\n    \"watch\": {\n      \"description\": \"Runs your workflow when the workflow's repository is starred.\",\n      \"one-of\": [\"null\", \"watch-mapping\"]\n    },\n    \"watch-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"watch-activity\"\n        }\n      }\n    },\n    \"watch-activity\": {\n      \"description\": \"The types of watch activity that trigger the workflow. Supported activity types: `started`.\",\n      \"one-of\": [\"watch-activity-type\", \"watch-activity-types\"]\n    },\n    \"watch-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"watch-activity-type\"\n      }\n    },\n    \"watch-activity-type\": {\n      \"allowed-values\": [\"started\"]\n    },\n    \"workflow-run-string\": {\n      \"description\": \"This event occurs when a workflow run is requested or completed. It allows you to execute a workflow based on execution or completion of another workflow. The workflow started by the `workflow_run` event is able to access secrets and write tokens, even if the previous workflow was not. This is useful in cases where the previous workflow is intentionally not privileged, but you need to take a privileged action in a later workflow.\",\n      \"string\": {\n        \"constant\": \"workflow_run\"\n      }\n    },\n    \"workflow-run\": {\n      \"description\": \"This event occurs when a workflow run is requested or completed. It allows you to execute a workflow based on execution or completion of another workflow. The workflow started by the `workflow_run` event is able to access secrets and write tokens, even if the previous workflow was not. This is useful in cases where the previous workflow is intentionally not privileged, but you need to take a privileged action in a later workflow.\",\n      \"one-of\": [\"null\", \"workflow-run-mapping\"]\n    },\n    \"workflow-run-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"workflow-run-activity\",\n          \"workflows\": \"workflow-run-workflows\",\n          \"branches\": \"event-branches\",\n          \"branches-ignore\": \"event-branches-ignore\"\n        }\n      }\n    },\n    \"workflow-run-workflows\": {\n      \"description\": \"The name of the workflow that triggers the `workflow_run` event. The workflow must be in the same repository as the workflow that uses the `workflow_run` event.\",\n      \"one-of\": [\"non-empty-string\", \"sequence-of-non-empty-string\"]\n    },\n    \"workflow-run-activity\": {\n      \"description\": \"The types of workflow run activity that trigger the workflow. Supported activity types: `completed`, `requested`, `in_progress`.\",\n      \"one-of\": [\"workflow-run-activity-type\", \"workflow-run-activity-types\"]\n    },\n    \"workflow-run-activity-types\": {\n      \"sequence\": {\n        \"item-type\": \"workflow-run-activity-type\"\n      }\n    },\n    \"workflow-run-activity-type\": {\n      \"allowed-values\": [\"requested\", \"completed\", \"in_progress\"]\n    },\n    \"event-branches\": {\n      \"description\": \"Use the `branches` filter when you want to include branch name patterns or when you want to both include and exclude branch name patterns. You cannot use both the `branches` and `branches-ignore` filters for the same event in a workflow.\",\n      \"one-of\": [\"non-empty-string\", \"sequence-of-non-empty-string\"]\n    },\n    \"event-branches-ignore\": {\n      \"description\": \"Use the `branches-ignore` filter when you only want to exclude branch name patterns. You cannot use both the `branches` and `branches-ignore` filters for the same event in a workflow.\",\n      \"one-of\": [\"non-empty-string\", \"sequence-of-non-empty-string\"]\n    },\n    \"event-tags\": {\n      \"description\": \"Use the `tags` filter when you want to include tag name patterns or when you want to both include and exclude tag names patterns. You cannot use both the `tags` and `tags-ignore` filters for the same event in a workflow.\",\n      \"one-of\": [\"non-empty-string\", \"sequence-of-non-empty-string\"]\n    },\n    \"event-tags-ignore\": {\n      \"description\": \"Use the `tags-ignore` filter when you only want to exclude tag name patterns. You cannot use both the `tags` and `tags-ignore` filters for the same event in a workflow.\",\n      \"one-of\": [\"non-empty-string\", \"sequence-of-non-empty-string\"]\n    },\n    \"event-paths\": {\n      \"description\": \"Use the `paths` filter when you want to include file path patterns or when you want to both include and exclude file path patterns. You cannot use both the `paths` and `paths-ignore` filters for the same event in a workflow.\",\n      \"one-of\": [\"non-empty-string\", \"sequence-of-non-empty-string\"]\n    },\n    \"event-paths-ignore\": {\n      \"description\": \"Use the `paths-ignore` filter when you only want to exclude file path patterns. You cannot use both the `paths` and `paths-ignore` filters for the same event in a workflow.\",\n      \"one-of\": [\"non-empty-string\", \"sequence-of-non-empty-string\"]\n    },\n    \"repository-dispatch-string\": {\n      \"description\": \"You can use the GitHub API to trigger a webhook event called `repository_dispatch` when you want to trigger a workflow for activity that happens outside of GitHub.\",\n      \"string\": {\n        \"constant\": \"branch_protection_rule\"\n      }\n    },\n    \"repository-dispatch\": {\n      \"description\": \"You can use the GitHub API to trigger a webhook event called `repository_dispatch` when you want to trigger a workflow for activity that happens outside of GitHub.\",\n      \"one-of\": [\"null\", \"repository-dispatch-mapping\"]\n    },\n    \"repository-dispatch-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"types\": \"sequence-of-non-empty-string\"\n        }\n      }\n    },\n    \"workflow-call-string\": {\n      \"description\": \"The `workflow_call` event is used to indicate that a workflow can be called by another workflow. When a workflow is triggered with the `workflow_call` event, the event payload in the called workflow is the same event payload from the calling workflow.\",\n      \"string\": {\n        \"constant\": \"workflow_call\"\n      }\n    },\n    \"workflow-call\": {\n      \"description\": \"The `workflow_call` event is used to indicate that a workflow can be called by another workflow. When a workflow is triggered with the `workflow_call` event, the event payload in the called workflow is the same event payload from the calling workflow.\",\n      \"one-of\": [\"null\", \"workflow-call-mapping\"]\n    },\n    \"workflow-call-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"inputs\": \"workflow-call-inputs\",\n          \"secrets\": \"workflow-call-secrets\",\n          \"outputs\": \"workflow-call-outputs\"\n        }\n      }\n    },\n    \"workflow-call-inputs\": {\n      \"description\": \"Inputs that are passed to the called workflow from the caller workflow.\",\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"workflow-call-input-definition\"\n      }\n    },\n    \"workflow-call-input-definition\": {\n      \"mapping\": {\n        \"properties\": {\n          \"description\": {\n            \"type\": \"string\",\n            \"description\": \"A string description of the input parameter.\"\n          },\n          \"type\": {\n            \"type\": \"workflow-call-input-type\",\n            \"required\": true\n          },\n          \"required\": {\n            \"type\": \"boolean\",\n            \"description\": \"A boolean to indicate whether the action requires the input parameter. Set to `true` when the parameter is required.\"\n          },\n          \"default\": \"workflow-call-input-default\"\n        }\n      }\n    },\n    \"workflow-call-input-type\": {\n      \"description\": \"Required if input is defined for the `on.workflow_call` keyword. The value of this parameter is a string specifying the data type of the input. This must be one of: `boolean`, `number`, or `string`.\",\n      \"one-of\": [\"input-type-string\", \"input-type-boolean\", \"input-type-number\"]\n    },\n    \"input-type-string\": {\n      \"string\": {\n        \"constant\": \"string\"\n      }\n    },\n    \"input-type-boolean\": {\n      \"string\": {\n        \"constant\": \"boolean\"\n      }\n    },\n    \"input-type-number\": {\n      \"string\": {\n        \"constant\": \"number\"\n      }\n    },\n    \"input-type-choice\": {\n      \"string\": {\n        \"constant\": \"choice\"\n      }\n    },\n    \"input-type-environment\": {\n      \"string\": {\n        \"constant\": \"environment\"\n      }\n    },\n    \"workflow-call-input-default\": {\n      \"description\": \"If a `default` parameter is not set, the default value of the input is `false` for boolean, `0` for a number, and `\\\"\\\"` for a string.\",\n      \"context\": [\"github\", \"inputs\", \"vars\"],\n      \"one-of\": [\"string\", \"boolean\", \"number\"]\n    },\n    \"workflow-call-secrets\": {\n      \"description\": \"A map of the secrets that can be used in the called workflow. Within the called workflow, you can use the `secrets` context to refer to a secret.\",\n      \"mapping\": {\n        \"loose-key-type\": \"workflow-call-secret-name\",\n        \"loose-value-type\": \"workflow-call-secret-definition\"\n      }\n    },\n    \"workflow-call-secret-name\": {\n      \"string\": {\n        \"require-non-empty\": true\n      },\n      \"description\": \"A string identifier to associate with the secret.\"\n    },\n    \"workflow-call-secret-definition\": {\n      \"one-of\": [\"null\", \"workflow-call-secret-mapping-definition\"]\n    },\n    \"workflow-call-secret-mapping-definition\": {\n      \"mapping\": {\n        \"properties\": {\n          \"description\": {\n            \"type\": \"string\",\n            \"description\": \"A string description of the secret parameter.\"\n          },\n          \"required\": {\n            \"type\": \"boolean\",\n            \"description\": \"A boolean specifying whether the secret must be supplied.\"\n          }\n        }\n      }\n    },\n    \"workflow-call-outputs\": {\n      \"description\": \"A reusable workflow may generate data that you want to use in the caller workflow. To use these outputs, you must specify them as the outputs of the reusable workflow.\",\n      \"mapping\": {\n        \"loose-key-type\": \"workflow-call-output-name\",\n        \"loose-value-type\": \"workflow-call-output-definition\"\n      }\n    },\n    \"workflow-call-output-name\": {\n      \"string\": {\n        \"require-non-empty\": true\n      },\n      \"description\": \"A string identifier to associate with the output. The value of `<output_id>` is a map of the input's metadata. The `<output_id>` must be a unique identifier within the outputs object and must start with a letter or _ and contain only alphanumeric characters, -, or _.\"\n    },\n    \"workflow-call-output-definition\": {\n      \"mapping\": {\n        \"properties\": {\n          \"description\": {\n            \"type\": \"string\",\n            \"description\": \"A string description of the output parameter.\"\n          },\n          \"value\": {\n            \"type\": \"workflow-output-context\",\n            \"required\": true\n          }\n        }\n      }\n    },\n    \"workflow-output-context\": {\n      \"description\": \"The value to assign to the output parameter.\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"jobs\"],\n      \"string\": {}\n    },\n    \"workflow-dispatch-string\": {\n      \"description\": \"The `workflow_dispatch` event allows you to manually trigger a workflow run. A workflow can be manually triggered using the GitHub API, GitHub CLI, or GitHub browser interface.\",\n      \"string\": {\n        \"constant\": \"workflow_dispatch\"\n      }\n    },\n    \"workflow-dispatch\": {\n      \"description\": \"The `workflow_dispatch` event allows you to manually trigger a workflow run. A workflow can be manually triggered using the GitHub API, GitHub CLI, or GitHub browser interface.\",\n      \"one-of\": [\"null\", \"workflow-dispatch-mapping\"]\n    },\n    \"workflow-dispatch-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"inputs\": \"workflow-dispatch-inputs\"\n        }\n      }\n    },\n    \"workflow-dispatch-inputs\": {\n      \"description\": \"You can configure custom-defined input properties, default input values, and required inputs for the event directly in your workflow. When you trigger the event, you can provide the `ref` and any `inputs`. When the workflow runs, you can access the input values in the `inputs` context.\",\n      \"mapping\": {\n        \"loose-key-type\": \"workflow-dispatch-input-name\",\n        \"loose-value-type\": \"workflow-dispatch-input\"\n      }\n    },\n    \"workflow-dispatch-input-name\": {\n      \"string\": {\n        \"require-non-empty\": true\n      },\n      \"description\": \"A string identifier to associate with the input. The value of <input_id> is a map of the input's metadata. The <input_id> must be a unique identifier within the inputs object. The <input_id> must start with a letter or _ and contain only alphanumeric characters, -, or _.\"\n    },\n    \"workflow-dispatch-input\": {\n      \"mapping\": {\n        \"properties\": {\n          \"description\": {\n            \"type\": \"string\",\n            \"description\": \"A string description of the input parameter.\"\n          },\n          \"type\": {\n            \"type\": \"workflow-dispatch-input-type\"\n          },\n          \"required\": {\n            \"type\": \"boolean\",\n            \"description\": \"A boolean to indicate whether the workflow requires the input parameter. Set to true when the parameter is required.\"\n          },\n          \"default\": \"workflow-dispatch-input-default\",\n          \"options\": {\n            \"type\": \"sequence-of-non-empty-string\",\n            \"description\": \"The options of the dropdown list, if the type is a choice.\"\n          }\n        }\n      }\n    },\n    \"workflow-dispatch-input-type\": {\n      \"description\": \"A string representing the type of the input. This must be one of: `boolean`, `number`, `string`, `choice`, or `environment`.\",\n      \"one-of\": [\n        \"input-type-string\",\n        \"input-type-boolean\",\n        \"input-type-number\",\n        \"input-type-environment\",\n        \"input-type-choice\"\n      ]\n    },\n    \"workflow-dispatch-input-default\": {\n      \"description\": \"The default value is used when an input parameter isn't specified in a workflow file.\",\n      \"one-of\": [\"string\", \"boolean\", \"number\"]\n    },\n    \"permissions\": {\n      \"description\": \"You can use `permissions` to modify the default permissions granted to the `GITHUB_TOKEN`, adding or removing access as required, so that you only allow the minimum required access.\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#permissions)\",\n      \"one-of\": [\n        \"permissions-mapping\",\n        \"permission-level-shorthand-read-all\",\n        \"permission-level-shorthand-write-all\"\n      ]\n    },\n    \"permissions-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"actions\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Actions workflows, workflow runs, and artifacts.\"\n          },\n          \"attestations\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Artifact attestations.\"\n          },\n          \"checks\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Check runs and check suites.\"\n          },\n          \"contents\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Repository contents, commits, branches, downloads, releases, and merges.\"\n          },\n          \"deployments\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Deployments and deployment statuses.\"\n          },\n          \"discussions\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Discussions and related comments and labels.\"\n          },\n          \"id-token\": {\n            \"type\": \"permission-level-write-or-no-access\",\n            \"description\": \"Token to request an OpenID Connect token.\"\n          },\n          \"issues\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Issues and related comments, assignees, labels, and milestones.\"\n          },\n          \"models\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Generate AI inference responses with GitHub Models.\"\n          },\n          \"packages\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Packages published to the GitHub Package Platform.\"\n          },\n          \"pages\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Retrieve Pages statuses, configuration, and builds, as well as create new builds.\"\n          },\n          \"pull-requests\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Pull requests and related comments, assignees, labels, milestones, and merges.\"\n          },\n          \"repository-projects\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Classic projects within a repository.\"\n          },\n          \"security-events\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Code scanning and Dependabot alerts.\"\n          },\n          \"statuses\": {\n            \"type\": \"permission-level-any\",\n            \"description\": \"Commit statuses.\"\n          }\n        }\n      }\n    },\n    \"permission-level-any\": {\n      \"description\": \"The permission level for the `GITHUB_TOKEN`.\",\n      \"one-of\": [\n        \"permission-level-read\",\n        \"permission-level-write\",\n        \"permission-level-no-access\"\n      ]\n    },\n    \"permission-level-read-or-no-access\": {\n      \"one-of\": [\"permission-level-read\", \"permission-level-no-access\"]\n    },\n    \"permission-level-write-or-no-access\": {\n      \"one-of\": [\"permission-level-write\", \"permission-level-no-access\"]\n    },\n    \"permission-level-read\": {\n      \"description\": \"The permission level for the `GITHUB_TOKEN`. Grants `read` permission for the specified scope.\",\n      \"string\": {\n        \"constant\": \"read\"\n      }\n    },\n    \"permission-level-write\": {\n      \"description\": \"The permission level for the `GITHUB_TOKEN`. Grants `write` permission for the specified scope.\",\n      \"string\": {\n        \"constant\": \"write\"\n      }\n    },\n    \"permission-level-no-access\": {\n      \"description\": \"The permission level for the `GITHUB_TOKEN`. Restricts all access for the specified scope.\",\n      \"string\": {\n        \"constant\": \"none\"\n      }\n    },\n    \"permission-level-shorthand-read-all\": {\n      \"description\": \"The permission level for the `GITHUB_TOKEN`. Grants `read` access for all scopes.\",\n      \"string\": {\n        \"constant\": \"read-all\"\n      }\n    },\n    \"permission-level-shorthand-write-all\": {\n      \"description\": \"The permission level for the `GITHUB_TOKEN`. Grants `write` access for all scopes.\",\n      \"string\": {\n        \"constant\": \"write-all\"\n      }\n    },\n    \"workflow-defaults\": {\n      \"description\": \"Use `defaults` to create a map of default settings that will apply to all jobs in the workflow. You can also set default settings that are only available to a job.\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#defaults)\",\n      \"mapping\": {\n        \"properties\": {\n          \"run\": \"workflow-defaults-run\"\n        }\n      }\n    },\n    \"workflow-defaults-run\": {\n      \"mapping\": {\n        \"properties\": {\n          \"shell\": \"shell\",\n          \"working-directory\": \"working-directory\"\n        }\n      }\n    },\n    \"workflow-env\": {\n      \"description\": \"A map of environment variables that are available to the steps of all jobs in the workflow. You can also set environment variables that are only available to the steps of a single job or to a single step.\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#env)\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"secrets\"],\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string\"\n      }\n    },\n    \"jobs\": {\n      \"description\": \"A workflow run is made up of one or more `jobs`, which run in parallel by default. To run jobs sequentially, you can define dependencies on other jobs using the `jobs.<job_id>.needs` keyword. Each job runs in a runner environment specified by `runs-on`.\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#jobs)\",\n      \"mapping\": {\n        \"loose-key-type\": \"job-id\",\n        \"loose-value-type\": \"job\"\n      }\n    },\n    \"job-id\": {\n      \"string\": {\n        \"require-non-empty\": true\n      },\n      \"description\": \"A unique identifier for the job. The identifier must start with a letter or _ and contain only alphanumeric characters, -, or _.\"\n    },\n    \"job\": {\n      \"description\": \"Each job must have an id to associate with the job. The key `job_id` is a string and its value is a map of the job's configuration data. You must replace `<job_id>` with a string that is unique to the jobs object. The `<job_id>` must start with a letter or _ and contain only alphanumeric characters, -, or _.\",\n      \"one-of\": [\"job-factory\", \"workflow-job\"]\n    },\n    \"job-factory\": {\n      \"mapping\": {\n        \"properties\": {\n          \"needs\": \"needs\",\n          \"if\": \"job-if\",\n          \"strategy\": \"strategy\",\n          \"name\": {\n            \"type\": \"string-strategy-context\",\n            \"description\": \"The name of the job displayed on GitHub.\"\n          },\n          \"runs-on\": {\n            \"type\": \"runs-on\",\n            \"required\": true\n          },\n          \"timeout-minutes\": {\n            \"type\": \"number-strategy-context\",\n            \"description\": \"The maximum number of minutes to let a workflow run before GitHub automatically cancels it. Default: 360\"\n          },\n          \"cancel-timeout-minutes\": \"number-strategy-context\",\n          \"continue-on-error\": {\n            \"type\": \"boolean-strategy-context\",\n            \"description\": \"Prevents a workflow run from failing when a job fails. Set to true to allow a workflow run to pass when this job fails.\"\n          },\n          \"container\": \"container\",\n          \"services\": \"services\",\n          \"env\": \"job-env\",\n          \"environment\": \"job-environment\",\n          \"permissions\": \"permissions\",\n          \"concurrency\": \"job-concurrency\",\n          \"outputs\": \"job-outputs\",\n          \"defaults\": \"job-defaults\",\n          \"steps\": \"steps\"\n        }\n      }\n    },\n    \"workflow-job\": {\n      \"mapping\": {\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string-strategy-context\",\n            \"description\": \"The name of the job displayed on GitHub.\"\n          },\n          \"uses\": {\n            \"description\": \"The location and version of a reusable workflow file to run as a job. Use one of the following formats:\\n\\n* `{owner}/{repo}/.github/workflows/{filename}@{ref}` for reusable workflows in public and private repositories.\\n* `./.github/workflows/{filename}` for reusable workflows in the same repository.\\n\\n{ref} can be a SHA, a release tag, or a branch name. Using the commit SHA is the safest for stability and security.\",\n            \"type\": \"non-empty-string\",\n            \"required\": true\n          },\n          \"with\": \"workflow-job-with\",\n          \"secrets\": \"workflow-job-secrets\",\n          \"needs\": \"needs\",\n          \"if\": \"job-if\",\n          \"permissions\": \"permissions\",\n          \"concurrency\": \"job-concurrency\",\n          \"strategy\": \"strategy\"\n        }\n      }\n    },\n    \"workflow-job-with\": {\n      \"description\": \"When a job is used to call a reusable workflow, you can use `with` to provide a map of inputs that are passed to the called workflow.\\n\\nAny inputs that you pass must match the input specifications defined in the called workflow.\",\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"scalar-needs-context\"\n      }\n    },\n    \"workflow-job-secrets\": {\n      \"description\": \"When a job is used to call a reusable workflow, you can use `secrets` to provide a map of secrets that are passed to the called workflow.\\n\\nAny secrets that you pass must match the names defined in the called workflow.\",\n      \"one-of\": [\"workflow-job-secrets-mapping\", \"workflow-job-secrets-inherit\"]\n    },\n    \"workflow-job-secrets-mapping\": {\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"scalar-needs-context-with-secrets\"\n      }\n    },\n    \"workflow-job-secrets-inherit\": {\n      \"string\": {\n        \"constant\": \"inherit\"\n      }\n    },\n    \"needs\": {\n      \"description\": \"Use `needs` to identify any jobs that must complete successfully before this job will run. It can be a string or array of strings. If a job fails, all jobs that need it are skipped unless the jobs use a conditional expression that causes the job to continue. If a run contains a series of jobs that need each other, a failure applies to all jobs in the dependency chain from the point of failure onwards.\",\n      \"one-of\": [\"sequence-of-non-empty-string\", \"non-empty-string\"]\n    },\n    \"job-if\": {\n      \"description\": \"You can use the `if` conditional to prevent a job from running unless a condition is met. You can use any supported context and expression to create a conditional.\",\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"always(0,0)\",\n        \"failure(0,MAX)\",\n        \"cancelled(0,0)\",\n        \"success(0,MAX)\"\n      ],\n      \"string\": {\n        \"is-expression\": true\n      }\n    },\n    \"job-if-result\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"always(0,0)\",\n        \"failure(0,MAX)\",\n        \"cancelled(0,0)\",\n        \"success(0,MAX)\"\n      ],\n      \"one-of\": [\"null\", \"boolean\", \"number\", \"string\", \"sequence\", \"mapping\"]\n    },\n    \"strategy\": {\n      \"description\": \"Use `strategy` to use a matrix strategy for your jobs. A matrix strategy lets you use variables in a single job definition to automatically create multiple job runs that are based on the combinations of the variables. \",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\"],\n      \"mapping\": {\n        \"properties\": {\n          \"fail-fast\": {\n            \"type\": \"boolean\",\n            \"description\": \"Setting `fail-fast` to `false` prevents GitHub from canceling all in-progress jobs if any matrix job fails. Default: `true`\"\n          },\n          \"max-parallel\": {\n            \"type\": \"number\",\n            \"description\": \"The maximum number of jobs that can run simultaneously when using a matrix job strategy. By default, GitHub will maximize the number of jobs run in parallel depending on runner availability.\"\n          },\n          \"matrix\": \"matrix\"\n        }\n      }\n    },\n    \"matrix\": {\n      \"description\": \"Use `matrix` to define a matrix of different job configurations. Within your matrix, define one or more variables followed by an array of values.\",\n      \"mapping\": {\n        \"properties\": {\n          \"include\": {\n            \"type\": \"matrix-filter\",\n            \"description\": \"Use `include` to expand existing matrix configurations or to add new configurations. The value of `include` is a list of objects.\\n\\nFor each object in the `include` list, the key:value pairs in the object will be added to each of the matrix combinations if none of the key:value pairs overwrite any of the original matrix values. If the object cannot be added to any of the matrix combinations, a new matrix combination will be created instead. Note that the original matrix values will not be overwritten, but added matrix values can be overwritten.\"\n          },\n          \"exclude\": {\n            \"type\": \"matrix-filter\",\n            \"description\": \"To remove specific configurations defined in the matrix, use `exclude`. An excluded configuration only has to be a partial match for it to be excluded.\"\n          }\n        },\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"sequence\"\n      }\n    },\n    \"matrix-filter\": {\n      \"sequence\": {\n        \"item-type\": \"matrix-filter-item\"\n      }\n    },\n    \"matrix-filter-item\": {\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"any\"\n      }\n    },\n    \"runs-on\": {\n      \"description\": \"Use `runs-on` to define the type of machine to run the job on.\\n* The destination machine can be either a GitHub-hosted runner, larger runner, or a self-hosted runner.\\n* You can target runners based on the labels assigned to them, or their group membership, or a combination of these.\\n* You can provide `runs-on` as a single string or as an array of strings.\\n* If you specify an array of strings, your workflow will execute on any runner that matches all of the specified `runs-on` values.\\n* If you would like to run your workflow on multiple machines, use `jobs.<job_id>.strategy`.\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"one-of\": [\n        \"non-empty-string\",\n        \"sequence-of-non-empty-string\",\n        \"runs-on-mapping\"\n      ]\n    },\n    \"runs-on-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"group\": {\n            \"description\": \"The group from which to select a runner.\",\n            \"type\": \"non-empty-string\"\n          },\n          \"labels\": \"runs-on-labels\"\n        }\n      }\n    },\n    \"runs-on-labels\": {\n      \"description\": \"The label by which to filter for available runners.\",\n      \"one-of\": [\"non-empty-string\", \"sequence-of-non-empty-string\"]\n    },\n    \"job-env\": {\n      \"description\": \"A map of variables that are available to all steps in the job.\",\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\"\n      ],\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string\"\n      }\n    },\n    \"workflow-concurrency\": {\n      \"description\": \"Concurrency ensures that only a single job or workflow using the same concurrency group will run at a time. A concurrency group can be any string or expression.\\n\\nYou can also specify `concurrency` at the job level.\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#concurrency)\",\n      \"context\": [\"github\", \"inputs\", \"vars\"],\n      \"one-of\": [\"string\", \"concurrency-mapping\"]\n    },\n    \"job-concurrency\": {\n      \"description\": \"Concurrency ensures that only a single job using the same concurrency group will run at a time. A concurrency group can be any string or expression. The expression can use any context except for the `secrets` context.\\n\\nYou can also specify `concurrency` at the workflow level.\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"one-of\": [\"non-empty-string\", \"concurrency-mapping\"]\n    },\n    \"concurrency-mapping\": {\n      \"description\": \"Concurrency ensures that only a single job or workflow using the same concurrency group will run at a time. A concurrency group can be any string or expression.\\n\\nYou can also specify `concurrency` at the job level.\\n\\n[Documentation](https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#concurrency)\",\n      \"mapping\": {\n        \"properties\": {\n          \"group\": {\n            \"type\": \"non-empty-string\",\n            \"required\": true,\n            \"description\": \"When a concurrent job or workflow is queued, if another job or workflow using the same concurrency group in the repository is in progress, the queued job or workflow will be `pending`. Any previously pending job or workflow in the concurrency group will be canceled. To also cancel any currently running job or workflow in the same concurrency group, specify `cancel-in-progress: true`.\"\n          },\n          \"cancel-in-progress\": {\n            \"type\": \"boolean\",\n            \"description\": \"To cancel any currently running job or workflow in the same concurrency group, specify cancel-in-progress: true.\"\n          }\n        }\n      }\n    },\n    \"job-environment\": {\n      \"description\": \"The environment that the job references. All environment protection rules must pass before a job referencing the environment is sent to a runner.\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"one-of\": [\"string\", \"job-environment-mapping\"]\n    },\n    \"job-environment-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"name\": {\n            \"type\": \"job-environment-name\",\n            \"required\": true\n          },\n          \"url\": {\n            \"type\": \"string-runner-context-no-secrets\",\n            \"description\": \"The environment URL, which maps to `environment_url` in the deployments API.\"\n          }\n        }\n      }\n    },\n    \"job-environment-name\": {\n      \"description\": \"The name of the environment used by the job.\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"string\": {}\n    },\n    \"job-defaults\": {\n      \"description\": \"A map of default settings that will apply to all steps in the job. You can also set default settings for the entire workflow.\",\n      \"mapping\": {\n        \"properties\": {\n          \"run\": \"job-defaults-run\"\n        }\n      }\n    },\n    \"job-defaults-run\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"strategy\",\n        \"matrix\",\n        \"needs\",\n        \"env\"\n      ],\n      \"mapping\": {\n        \"properties\": {\n          \"shell\": \"shell\",\n          \"working-directory\": \"working-directory\"\n        }\n      }\n    },\n    \"job-outputs\": {\n      \"description\": \"A map of outputs for a called workflow. Called workflow outputs are available to all downstream jobs in the caller workflow. Each output has an identifier, an optional `description,` and a `value`. The `value` must be set to the value of an output from a job within the called workflow.\",\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string-runner-context\"\n      }\n    },\n    \"steps\": {\n      \"description\": \"A job contains a sequence of tasks called `steps`. Steps can run commands, run setup tasks, or run an action in your repository, a public repository, or an action published in a Docker registry. Not all steps run actions, but all actions run as a step. Each step runs in its own process in the runner environment and has access to the workspace and filesystem. Because steps run in their own process, changes to environment variables are not preserved between steps. GitHub provides built-in steps to set up and complete a job. Must contain either `uses` or `run`.\",\n      \"sequence\": {\n        \"item-type\": \"steps-item\"\n      }\n    },\n    \"steps-item\": {\n      \"one-of\": [\"run-step\", \"regular-step\"]\n    },\n    \"run-step\": {\n      \"mapping\": {\n        \"properties\": {\n          \"name\": \"step-name\",\n          \"id\": \"step-id\",\n          \"if\": \"step-if\",\n          \"timeout-minutes\": \"step-timeout-minutes\",\n          \"run\": {\n            \"type\": \"string-steps-context\",\n            \"description\": \"Runs command-line programs using the operating system's shell. If you do not provide a `name`, the step name will default to the text specified in the `run` command. Commands run using non-login shells by default. You can choose a different shell and customize the shell used to run commands. Each `run` keyword represents a new process and shell in the virtual environment. When you provide multi-line commands, each line runs in the same shell.\",\n            \"required\": true\n          },\n          \"continue-on-error\": \"step-continue-on-error\",\n          \"env\": \"step-env\",\n          \"working-directory\": \"string-steps-context\",\n          \"shell\": \"shell\"\n        }\n      }\n    },\n    \"regular-step\": {\n      \"mapping\": {\n        \"properties\": {\n          \"name\": \"step-name\",\n          \"id\": \"step-id\",\n          \"if\": \"step-if\",\n          \"continue-on-error\": \"step-continue-on-error\",\n          \"timeout-minutes\": \"step-timeout-minutes\",\n          \"uses\": {\n            \"type\": \"step-uses\",\n            \"required\": true\n          },\n          \"with\": \"step-with\",\n          \"env\": \"step-env\"\n        }\n      }\n    },\n    \"step-uses\": {\n      \"description\": \"Selects an action to run as part of a step in your job. An action is a reusable unit of code. You can use an action defined in the same repository as the workflow, a public repository, or in a published Docker container image.\",\n      \"string\": {\n        \"require-non-empty\": true\n      }\n    },\n    \"step-continue-on-error\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"boolean\": {},\n      \"description\": \"Prevents a job from failing when a step fails. Set to `true` to allow a job to pass when this step fails.\"\n    },\n    \"step-id\": {\n      \"string\": {\n        \"require-non-empty\": true\n      },\n      \"description\": \"A unique identifier for the step. You can use the `id` to reference the step in contexts.\"\n    },\n    \"step-if\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"always(0,0)\",\n        \"failure(0,0)\",\n        \"cancelled(0,0)\",\n        \"success(0,0)\",\n        \"hashFiles(1,255)\"\n      ],\n      \"description\": \"Use the `if` conditional to prevent a step from running unless a condition is met. Any supported context and expression can be used to create a conditional. Expressions in an `if` conditional do not require the bracketed expression syntax. When you use expressions in an `if` conditional, you may omit the expression syntax because GitHub automatically evaluates the `if` conditional as an expression.\",\n      \"string\": {\n        \"is-expression\": true\n      }\n    },\n    \"step-if-result\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"always(0,0)\",\n        \"failure(0,0)\",\n        \"cancelled(0,0)\",\n        \"success(0,0)\",\n        \"hashFiles(1,255)\"\n      ],\n      \"one-of\": [\"null\", \"boolean\", \"number\", \"string\", \"sequence\", \"mapping\"]\n    },\n    \"step-env\": {\n      \"description\": \"Sets variables for steps to use in the runner environment. You can also set variables for the entire workflow or a job.\",\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string\"\n      }\n    },\n    \"step-name\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"string\": {},\n      \"description\": \"A name for your step to display on GitHub.\"\n    },\n    \"step-timeout-minutes\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"number\": {},\n      \"description\": \"The maximum number of minutes to run the step before killing the process.\"\n    },\n    \"step-with\": {\n      \"description\": \"A map of the input parameters defined by the action. Each input parameter is a key/value pair. Input parameters are set as variables. When you specify an input in a workflow file or use a default input value, GitHub creates a variable for the input with the name `INPUT_<VARIABLE_NAME>`. The variable created converts input names to uppercase letters and replaces spaces with `_`.\",\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string\"\n      }\n    },\n    \"container\": {\n      \"description\": \"A container to run any steps in a job that don't already specify a container. If you have steps that use both script and container actions, the container actions will run as sibling containers on the same network with the same volume mounts.\\n\\nIf you do not set a container, all steps will run directly on the host specified by runs-on unless a step refers to an action configured to run in a container.\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"one-of\": [\"string\", \"container-mapping\"]\n    },\n    \"container-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"image\": {\n            \"type\": \"non-empty-string\",\n            \"description\": \"Use `jobs.<job_id>.container.image` to define the Docker image to use as the container to run the action. The value can be the Docker Hub image or a registry name.\"\n          },\n          \"options\": {\n            \"type\": \"non-empty-string\",\n            \"description\": \"Use `jobs.<job_id>.container.options` to configure additional Docker container resource options.\"\n          },\n          \"env\": \"container-env\",\n          \"ports\": {\n            \"type\": \"sequence-of-non-empty-string\",\n            \"description\": \"Use `jobs.<job_id>.container.ports` to set an array of ports to expose on the container.\"\n          },\n          \"volumes\": {\n            \"type\": \"sequence-of-non-empty-string\",\n            \"description\": \"Use `jobs.<job_id>.container.volumes` to set an array of volumes for the container to use. You can use volumes to share data between services or other steps in a job. You can specify named Docker volumes, anonymous Docker volumes, or bind mounts on the host.\"\n          },\n          \"credentials\": \"container-registry-credentials\"\n        }\n      }\n    },\n    \"services\": {\n      \"description\": \"Additional containers to host services for a job in a workflow. These are useful for creating databases or cache services like redis. The runner on the virtual machine will automatically create a network and manage the life cycle of the service containers. When you use a service container for a job or your step uses container actions, you don't need to set port information to access the service. Docker automatically exposes all ports between containers on the same network. When both the job and the action run in a container, you can directly reference the container by its hostname. The hostname is automatically mapped to the service name. When a step does not use a container action, you must access the service using localhost and bind the ports.\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"services-container\"\n      }\n    },\n    \"services-container\": {\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"one-of\": [\"non-empty-string\", \"container-mapping\"]\n    },\n    \"container-registry-credentials\": {\n      \"description\": \"If the image's container registry requires authentication to pull the image, you can use `jobs.<job_id>.container.credentials` to set a map of the username and password. The credentials are the same values that you would provide to the `docker login` command.\",\n      \"context\": [\"github\", \"inputs\", \"vars\", \"secrets\", \"env\"],\n      \"mapping\": {\n        \"properties\": {\n          \"username\": \"non-empty-string\",\n          \"password\": \"non-empty-string\"\n        }\n      }\n    },\n    \"container-env\": {\n      \"description\": \"Use `jobs.<job_id>.container.env` to set a map of variables in the container.\",\n      \"mapping\": {\n        \"loose-key-type\": \"non-empty-string\",\n        \"loose-value-type\": \"string-runner-context\"\n      }\n    },\n    \"non-empty-string\": {\n      \"string\": {\n        \"require-non-empty\": true\n      }\n    },\n    \"sequence-of-non-empty-string\": {\n      \"sequence\": {\n        \"item-type\": \"non-empty-string\"\n      }\n    },\n    \"boolean-needs-context\": {\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\"],\n      \"boolean\": {}\n    },\n    \"number-needs-context\": {\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\"],\n      \"number\": {}\n    },\n    \"string-needs-context\": {\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\"],\n      \"string\": {}\n    },\n    \"scalar-needs-context\": {\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"one-of\": [\"string\", \"boolean\", \"number\"]\n    },\n    \"scalar-needs-context-with-secrets\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"secrets\",\n        \"strategy\",\n        \"matrix\"\n      ],\n      \"one-of\": [\"string\", \"boolean\", \"number\"]\n    },\n    \"boolean-strategy-context\": {\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"boolean\": {}\n    },\n    \"number-strategy-context\": {\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"number\": {}\n    },\n    \"string-strategy-context\": {\n      \"context\": [\"github\", \"inputs\", \"vars\", \"needs\", \"strategy\", \"matrix\"],\n      \"string\": {}\n    },\n    \"boolean-steps-context\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"boolean\": {}\n    },\n    \"number-steps-context\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"number\": {}\n    },\n    \"string-runner-context\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\"\n      ],\n      \"string\": {}\n    },\n    \"string-runner-context-no-secrets\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\"\n      ],\n      \"string\": {}\n    },\n    \"string-steps-context\": {\n      \"context\": [\n        \"github\",\n        \"inputs\",\n        \"vars\",\n        \"needs\",\n        \"strategy\",\n        \"matrix\",\n        \"secrets\",\n        \"steps\",\n        \"job\",\n        \"runner\",\n        \"env\",\n        \"hashFiles(1,255)\"\n      ],\n      \"string\": {}\n    },\n    \"shell\": {\n      \"string\": {\n        \"require-non-empty\": true\n      },\n      \"description\": \"Use `shell` to override the default shell settings in the runner's operating system. You can use built-in shell keywords, or you can define a custom set of shell options. The shell command that is run internally executes a temporary file that contains the commands specified in `run`.\"\n    },\n    \"working-directory\": {\n      \"string\": {\n        \"require-non-empty\": true\n      },\n      \"description\": \"The `working-directory` keyword specifies the working directory where the command is run.\"\n    },\n    \"cron-mapping\": {\n      \"mapping\": {\n        \"properties\": {\n          \"cron\": \"cron-pattern\"\n        }\n      }\n    },\n    \"cron-pattern\": {\n      \"string\": {\n        \"require-non-empty\": true\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "pkg/workflowpattern/trace_writer.go",
    "content": "package workflowpattern\n\nimport \"fmt\"\n\ntype TraceWriter interface {\n\tInfo(string, ...interface{})\n}\n\ntype EmptyTraceWriter struct{}\n\nfunc (*EmptyTraceWriter) Info(string, ...interface{}) {\n}\n\ntype StdOutTraceWriter struct{}\n\nfunc (*StdOutTraceWriter) Info(format string, args ...interface{}) {\n\tfmt.Printf(format+\"\\n\", args...)\n}\n"
  },
  {
    "path": "pkg/workflowpattern/workflow_pattern.go",
    "content": "package workflowpattern\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\ntype WorkflowPattern struct {\n\tPattern  string\n\tNegative bool\n\tRegex    *regexp.Regexp\n}\n\nfunc CompilePattern(rawpattern string) (*WorkflowPattern, error) {\n\tnegative := false\n\tpattern := rawpattern\n\tif strings.HasPrefix(rawpattern, \"!\") {\n\t\tnegative = true\n\t\tpattern = rawpattern[1:]\n\t}\n\trpattern, err := PatternToRegex(pattern)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tregex, err := regexp.Compile(rpattern)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &WorkflowPattern{\n\t\tPattern:  pattern,\n\t\tNegative: negative,\n\t\tRegex:    regex,\n\t}, nil\n}\n\n//nolint:gocyclo\nfunc PatternToRegex(pattern string) (string, error) {\n\tvar rpattern strings.Builder\n\trpattern.WriteString(\"^\")\n\tpos := 0\n\terrors := map[int]string{}\n\tfor pos < len(pattern) {\n\t\tswitch pattern[pos] {\n\t\tcase '*':\n\t\t\tif pos+1 < len(pattern) && pattern[pos+1] == '*' {\n\t\t\t\tif pos+2 < len(pattern) && pattern[pos+2] == '/' {\n\t\t\t\t\trpattern.WriteString(\"(.+/)?\")\n\t\t\t\t\tpos += 3\n\t\t\t\t} else {\n\t\t\t\t\trpattern.WriteString(\".*\")\n\t\t\t\t\tpos += 2\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trpattern.WriteString(\"[^/]*\")\n\t\t\t\tpos++\n\t\t\t}\n\t\tcase '+', '?':\n\t\t\tif pos > 0 {\n\t\t\t\trpattern.WriteByte(pattern[pos])\n\t\t\t} else {\n\t\t\t\trpattern.WriteString(regexp.QuoteMeta(string([]byte{pattern[pos]})))\n\t\t\t}\n\t\t\tpos++\n\t\tcase '[':\n\t\t\trpattern.WriteByte(pattern[pos])\n\t\t\tpos++\n\t\t\tif pos < len(pattern) && pattern[pos] == ']' {\n\t\t\t\terrors[pos] = \"Unexpected empty brackets '[]'\"\n\t\t\t\tpos++\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tvalidChar := func(a, b, test byte) bool {\n\t\t\t\treturn test >= a && test <= b\n\t\t\t}\n\t\t\tstartPos := pos\n\t\t\tfor pos < len(pattern) && pattern[pos] != ']' {\n\t\t\t\tswitch pattern[pos] {\n\t\t\t\tcase '-':\n\t\t\t\t\tif pos <= startPos || pos+1 >= len(pattern) {\n\t\t\t\t\t\terrors[pos] = \"Invalid range\"\n\t\t\t\t\t\tpos++\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tvalidRange := func(a, b byte) bool {\n\t\t\t\t\t\treturn validChar(a, b, pattern[pos-1]) && validChar(a, b, pattern[pos+1]) && pattern[pos-1] <= pattern[pos+1]\n\t\t\t\t\t}\n\t\t\t\t\tif !validRange('A', 'z') && !validRange('0', '9') {\n\t\t\t\t\t\terrors[pos] = \"Ranges can only include a-z, A-Z, A-z, and 0-9\"\n\t\t\t\t\t\tpos++\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\trpattern.WriteString(pattern[pos : pos+2])\n\t\t\t\t\tpos += 2\n\t\t\t\tdefault:\n\t\t\t\t\tif !validChar('A', 'z', pattern[pos]) && !validChar('0', '9', pattern[pos]) {\n\t\t\t\t\t\terrors[pos] = \"Ranges can only include a-z, A-Z and 0-9\"\n\t\t\t\t\t\tpos++\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\trpattern.WriteString(regexp.QuoteMeta(string([]byte{pattern[pos]})))\n\t\t\t\t\tpos++\n\t\t\t\t}\n\t\t\t}\n\t\t\tif pos >= len(pattern) || pattern[pos] != ']' {\n\t\t\t\terrors[pos] = \"Missing closing bracket ']' after '['\"\n\t\t\t\tpos++\n\t\t\t}\n\t\t\trpattern.WriteString(\"]\")\n\t\t\tpos++\n\t\tcase '\\\\':\n\t\t\tif pos+1 >= len(pattern) {\n\t\t\t\terrors[pos] = \"Missing symbol after \\\\\"\n\t\t\t\tpos++\n\t\t\t\tbreak\n\t\t\t}\n\t\t\trpattern.WriteString(regexp.QuoteMeta(string([]byte{pattern[pos+1]})))\n\t\t\tpos += 2\n\t\tdefault:\n\t\t\trpattern.WriteString(regexp.QuoteMeta(string([]byte{pattern[pos]})))\n\t\t\tpos++\n\t\t}\n\t}\n\tif len(errors) > 0 {\n\t\tvar errorMessage strings.Builder\n\t\tfor position, err := range errors {\n\t\t\tif errorMessage.Len() > 0 {\n\t\t\t\terrorMessage.WriteString(\", \")\n\t\t\t}\n\t\t\terrorMessage.WriteString(fmt.Sprintf(\"Position: %d Error: %s\", position, err))\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"invalid Pattern '%s': %s\", pattern, errorMessage.String())\n\t}\n\trpattern.WriteString(\"$\")\n\treturn rpattern.String(), nil\n}\n\nfunc CompilePatterns(patterns ...string) ([]*WorkflowPattern, error) {\n\tret := []*WorkflowPattern{}\n\tfor _, pattern := range patterns {\n\t\tcp, err := CompilePattern(pattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tret = append(ret, cp)\n\t}\n\treturn ret, nil\n}\n\n// returns true if the workflow should be skipped paths/branches\nfunc Skip(sequence []*WorkflowPattern, input []string, traceWriter TraceWriter) bool {\n\tif len(sequence) == 0 {\n\t\treturn false\n\t}\n\tfor _, file := range input {\n\t\tmatched := false\n\t\tfor _, item := range sequence {\n\t\t\tif item.Regex.MatchString(file) {\n\t\t\t\tpattern := item.Pattern\n\t\t\t\tif item.Negative {\n\t\t\t\t\tmatched = false\n\t\t\t\t\ttraceWriter.Info(\"%s excluded by pattern %s\", file, pattern)\n\t\t\t\t} else {\n\t\t\t\t\tmatched = true\n\t\t\t\t\ttraceWriter.Info(\"%s included by pattern %s\", file, pattern)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif matched {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// returns true if the workflow should be skipped paths-ignore/branches-ignore\nfunc Filter(sequence []*WorkflowPattern, input []string, traceWriter TraceWriter) bool {\n\tif len(sequence) == 0 {\n\t\treturn false\n\t}\n\tfor _, file := range input {\n\t\tmatched := false\n\t\tfor _, item := range sequence {\n\t\t\tif item.Regex.MatchString(file) == !item.Negative {\n\t\t\t\tpattern := item.Pattern\n\t\t\t\ttraceWriter.Info(\"%s ignored by pattern %s\", file, pattern)\n\t\t\t\tmatched = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !matched {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "pkg/workflowpattern/workflow_pattern_test.go",
    "content": "package workflowpattern\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestMatchPattern(t *testing.T) {\n\tkases := []struct {\n\t\tinputs       []string\n\t\tpatterns     []string\n\t\tskipResult   bool\n\t\tfilterResult bool\n\t}{\n\t\t{\n\t\t\tpatterns:     []string{\"*\"},\n\t\t\tinputs:       []string{\"path/with/slash\"},\n\t\t\tskipResult:   true,\n\t\t\tfilterResult: false,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"path/a\", \"path/b\", \"path/c\"},\n\t\t\tinputs:       []string{\"meta\", \"path/b\", \"otherfile\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: false,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"path/a\", \"path/b\", \"path/c\"},\n\t\t\tinputs:       []string{\"path/b\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"path/a\", \"path/b\", \"path/c\"},\n\t\t\tinputs:       []string{\"path/c\", \"path/b\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"path/a\", \"path/b\", \"path/c\"},\n\t\t\tinputs:       []string{\"path/c\", \"path/b\", \"path/a\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"path/a\", \"path/b\", \"path/c\"},\n\t\t\tinputs:       []string{\"path/c\", \"path/b\", \"path/d\", \"path/a\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: false,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{},\n\t\t\tinputs:       []string{},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: false,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"\\\\!file\"},\n\t\t\tinputs:       []string{\"!file\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"escape\\\\\\\\backslash\"},\n\t\t\tinputs:       []string{\"escape\\\\backslash\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\".yml\"},\n\t\t\tinputs:       []string{\"fyml\"},\n\t\t\tskipResult:   true,\n\t\t\tfilterResult: false,\n\t\t},\n\t\t// https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#patterns-to-match-branches-and-tags\n\t\t{\n\t\t\tpatterns:     []string{\"feature/*\"},\n\t\t\tinputs:       []string{\"feature/my-branch\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"feature/*\"},\n\t\t\tinputs:       []string{\"feature/your-branch\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"feature/**\"},\n\t\t\tinputs:       []string{\"feature/beta-a/my-branch\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"feature/**\"},\n\t\t\tinputs:       []string{\"feature/beta-a/my-branch\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"feature/**\"},\n\t\t\tinputs:       []string{\"feature/mona/the/octocat\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"main\", \"releases/mona-the-octocat\"},\n\t\t\tinputs:       []string{\"main\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"main\", \"releases/mona-the-octocat\"},\n\t\t\tinputs:       []string{\"releases/mona-the-octocat\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*\"},\n\t\t\tinputs:       []string{\"main\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*\"},\n\t\t\tinputs:       []string{\"releases\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**\"},\n\t\t\tinputs:       []string{\"all/the/branches\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**\"},\n\t\t\tinputs:       []string{\"every/tag\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*feature\"},\n\t\t\tinputs:       []string{\"mona-feature\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*feature\"},\n\t\t\tinputs:       []string{\"feature\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*feature\"},\n\t\t\tinputs:       []string{\"ver-10-feature\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"v2*\"},\n\t\t\tinputs:       []string{\"v2\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"v2*\"},\n\t\t\tinputs:       []string{\"v2.0\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"v2*\"},\n\t\t\tinputs:       []string{\"v2.9\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"v[12].[0-9]+.[0-9]+\"},\n\t\t\tinputs:       []string{\"v1.10.1\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"v[12].[0-9]+.[0-9]+\"},\n\t\t\tinputs:       []string{\"v2.0.0\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t// https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#patterns-to-match-file-paths\n\t\t{\n\t\t\tpatterns:     []string{\"*\"},\n\t\t\tinputs:       []string{\"README.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*\"},\n\t\t\tinputs:       []string{\"server.rb\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.jsx?\"},\n\t\t\tinputs:       []string{\"page.js\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.jsx?\"},\n\t\t\tinputs:       []string{\"page.jsx\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**\"},\n\t\t\tinputs:       []string{\"all/the/files.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.js\"},\n\t\t\tinputs:       []string{\"app.js\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.js\"},\n\t\t\tinputs:       []string{\"index.js\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**.js\"},\n\t\t\tinputs:       []string{\"index.js\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**.js\"},\n\t\t\tinputs:       []string{\"js/index.js\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**.js\"},\n\t\t\tinputs:       []string{\"src/js/app.js\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"docs/*\"},\n\t\t\tinputs:       []string{\"docs/README.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"docs/*\"},\n\t\t\tinputs:       []string{\"docs/file.txt\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"docs/**\"},\n\t\t\tinputs:       []string{\"docs/README.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"docs/**\"},\n\t\t\tinputs:       []string{\"docs/mona/octocat.txt\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"docs/**/*.md\"},\n\t\t\tinputs:       []string{\"docs/README.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"docs/**/*.md\"},\n\t\t\tinputs:       []string{\"docs/mona/hello-world.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"docs/**/*.md\"},\n\t\t\tinputs:       []string{\"docs/a/markdown/file.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/docs/**\"},\n\t\t\tinputs:       []string{\"docs/hello.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/docs/**\"},\n\t\t\tinputs:       []string{\"dir/docs/my-file.txt\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/docs/**\"},\n\t\t\tinputs:       []string{\"space/docs/plan/space.doc\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/README.md\"},\n\t\t\tinputs:       []string{\"README.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/README.md\"},\n\t\t\tinputs:       []string{\"js/README.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/*src/**\"},\n\t\t\tinputs:       []string{\"a/src/app.js\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/*src/**\"},\n\t\t\tinputs:       []string{\"my-src/code/js/app.js\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/*-post.md\"},\n\t\t\tinputs:       []string{\"my-post.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/*-post.md\"},\n\t\t\tinputs:       []string{\"path/their-post.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/migrate-*.sql\"},\n\t\t\tinputs:       []string{\"migrate-10909.sql\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/migrate-*.sql\"},\n\t\t\tinputs:       []string{\"db/migrate-v1.0.sql\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"**/migrate-*.sql\"},\n\t\t\tinputs:       []string{\"db/sept/migrate-v1.sql\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.md\", \"!README.md\"},\n\t\t\tinputs:       []string{\"hello.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.md\", \"!README.md\"},\n\t\t\tinputs:       []string{\"README.md\"},\n\t\t\tskipResult:   true,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.md\", \"!README.md\"},\n\t\t\tinputs:       []string{\"docs/hello.md\"},\n\t\t\tskipResult:   true,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.md\", \"!README.md\", \"README*\"},\n\t\t\tinputs:       []string{\"hello.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.md\", \"!README.md\", \"README*\"},\n\t\t\tinputs:       []string{\"README.md\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t\t{\n\t\t\tpatterns:     []string{\"*.md\", \"!README.md\", \"README*\"},\n\t\t\tinputs:       []string{\"README.doc\"},\n\t\t\tskipResult:   false,\n\t\t\tfilterResult: true,\n\t\t},\n\t}\n\n\tfor _, kase := range kases {\n\t\tt.Run(strings.Join(kase.patterns, \",\"), func(t *testing.T) {\n\t\t\tpatterns, err := CompilePatterns(kase.patterns...)\n\t\t\tassert.NoError(t, err)\n\n\t\t\tassert.EqualValues(t, kase.skipResult, Skip(patterns, kase.inputs, &StdOutTraceWriter{}), \"skipResult\")\n\t\t\tassert.EqualValues(t, kase.filterResult, Filter(patterns, kase.inputs, &StdOutTraceWriter{}), \"filterResult\")\n\t\t})\n\t}\n}\n"
  }
]